package com.dhcc.sds.standard.function;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.dhcc.cdc.busi.dao.CdcBsEmrStructMapper;
import com.dhcc.cdc.busi.dao.CdcBsExamStructMapper;
import com.dhcc.cdc.busi.dao.CdcEpisodeMapper;
import com.dhcc.cdc.busi.dao.CdcSurgeryMapper;
import com.dhcc.cdc.busi.entity.*;
import com.dhcc.cdc.busi.service.*;
import com.dhcc.cdc.sys.cache.config.CdcConfigCache;
import com.dhcc.cdc.sys.dao.DictionaryMapper;
import com.dhcc.cdc.sys.entity.DictionaryEntity;
import com.dhcc.cdc.sys.service.IDictionaryService;
import com.dhcc.core.framework.util.CommonUtil;
import com.dhcc.core.framework.util.DateUtil;
import com.dhcc.core.framework.util.ObjectUtil;
import com.dhcc.core.framework.util.SpringContextHolder;
import com.dhcc.sdc.base.entity.ContraindicationEntity;
import com.dhcc.sdc.base.service.IContraindicationService;
import com.dhcc.sdc.busi.entity.SdcBusiContraindicationEntity;
import com.dhcc.sdc.busi.service.ISdcBusiContraindicationService;
import com.dhcc.sdc.busi.service.ISdcBusiEvaluationService;
import com.dhcc.sds.base.cache.formitem.FormItemCache;
import com.dhcc.sds.base.cache.formitemdic.FormItemDicCache;
import com.dhcc.sds.base.cache.qcentity.QcEntityCache;
import com.dhcc.sds.base.dao.SdsDataConfigMapper;
import com.dhcc.sds.base.dao.SdsDicMapper;
import com.dhcc.sds.base.dao.SdsFunctionMapper;
import com.dhcc.sds.base.entity.*;
import com.dhcc.sds.base.service.ISdsDataConfigService;
import com.dhcc.sds.base.service.ISdsQcentityRuleService;
import com.dhcc.sds.busi.entity.SdsQcfitemExecresultEntity;
import com.dhcc.sds.busi.entity.SdsQcincaseEntity;
import com.dhcc.sds.busi.entity.SdsQcincaseOperlogEntity;
import com.dhcc.sds.busi.service.ISdsQcfitemExecresultService;
import com.dhcc.sds.busi.service.ISdsQcincaseOperlogService;
import com.dhcc.sds.busi.service.ISdsQcincaseService;
import com.dhcc.sds.standard.dao.SdsStandDicMapper;
import com.dhcc.sds.standard.dao.SdsStandDicMatchMapper;
import com.dhcc.sds.standard.dao.SdsStandDicMatchParamMapper;
import com.dhcc.sds.standard.dao.SdsStandSourceMapper;
import com.dhcc.sds.standard.entity.*;
import com.dhcc.sds.standard.service.ISdsStandDicService;
import com.dhcc.sds.util.NLPUtil;
import org.apache.commons.lang.text.StrSubstitutor;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
import java.io.IOException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * @Description: 项目取值函数类
 * @author:sunyj
 * @date:2023年11月24日08:54:18
 * @Copyright: (c) DHCC All rights reserved.
 */
@Service("getValueSrv")
public class GetValueSrv {
    static SdsStandSourceMapper sdsStandSourceMapper = SpringContextHolder.getBean("sdsStandSourceMapper");
    static CdcEpisodeMapper cdcEpisodeMapper = SpringContextHolder.getBean("cdcEpisodeMapper");
    static ICdcDictionaryService cdcDictionaryService = SpringContextHolder.getBean("cdcDictionaryService");
    static ICdcTransferService cdcTransferService = SpringContextHolder.getBean("cdcTransferService");
    static ICdcLocationService cdcLocationService = SpringContextHolder.getBean("cdcLocationService");
    static ICdcOrdexecService cdcOrdexecService = SpringContextHolder.getBean("cdcOrdexecService");
    static ICdcOrdmastService cdcOrdmastService = SpringContextHolder.getBean("cdcOrdmastService");
    static SdsFunctionMapper sdsFunctionMapper = SpringContextHolder.getBean("sdsFunctionMapper");
    static ISdcBusiEvaluationService sdcBusiEvaluationService = SpringContextHolder.getBean("sdcBusiEvaluationService");
    static SdsStandDicMapper sdsStandDicMapper = SpringContextHolder.getBean("sdsStandDicMapper");
    static DictionaryMapper dictionaryMapper = SpringContextHolder.getBean("dictionaryMapper");
    static CdcSurgeryMapper cdcSurgeryMapper = SpringContextHolder.getBean("cdcSurgeryMapper");
    static SdsStandDicMatchMapper sdsStandDicMatchMapper = SpringContextHolder.getBean("sdsStandDicMatchMapper");
    static SdsStandDicMatchParamMapper sdsStandDicMatchParamMapper = SpringContextHolder.getBean("sdsStandDicMatchParamMapper");
    static IDictionaryService dictionaryService = SpringContextHolder.getBean("dictionaryService");
    static CdcBsEmrStructMapper cdcBsEmrStructMapper = SpringContextHolder.getBean("cdcBsEmrStructMapper");
    static CdcBsExamStructMapper cdcBsExamStructMapper = SpringContextHolder.getBean("cdcBsExamStructMapper");
    static IContraindicationService baseContraindicationService = SpringContextHolder.getBean("contraindicationService");
    static ISdcBusiContraindicationService sdcBusiContraindicationService = SpringContextHolder.getBean("sdcBusiContraindicationService");
    static ISdsQcincaseService sdsQcincaseService = SpringContextHolder.getBean("sdsQcincaseService");
    static ISdsQcincaseOperlogService sdsQcincaseOperlogService = SpringContextHolder.getBean("sdsQcincaseOperlogService");
    static ISdsQcentityRuleService sdsQcentityRuleService = SpringContextHolder.getBean("sdsQcentityRuleService");
    static ISdsStandDicService sdsStandDicService = SpringContextHolder.getBean("sdsStandDicService");
    static ISdsQcfitemExecresultService sdsQcfitemExecresultService = SpringContextHolder.getBean("sdsQcfitemExecresultService");

    Logger log = LoggerFactory.getLogger(this.getClass());

    /**
     * 获取病人HIS数据-就诊信息
     */
    public Object Episode(Long episodeId, Long datasourceId, Integer currentTime, Long dicId, Long valueTime) {
        String resultVal = "";
        List<List<Map<String, Object>>> resultList = new ArrayList<>();

        SdsStandSourceEntity source = sdsStandSourceMapper.selectById(datasourceId);
        if (!CommonUtil.isEmpty(source)) {
            String sourceCode = source.getSourceCode();
            switch (sourceCode) {
                case "OEDateT":
                    //到达本院急诊或者门诊日期时间
                    CdcEpisodeEntity cdcEpisodeEntity = cdcEpisodeMapper.selectById(episodeId);
                    if (CommonUtil.isNotEmpty(cdcEpisodeEntity.getOeDate())) {
                        resultVal = DateUtil.format(cdcEpisodeEntity.getOeDate(), "yyyy-MM-dd HH:mm:ss");
                    }
                    break;
                case "InDeptDate":
                    //入住某科室日期时间
                    if (!StringUtils.isEmpty(dicId)) {
                        //先查询就诊科室
                        Map<String, String> mapParam = handleDicMatchParam(dicId, 3);
                        //直接从转科记录取值
                        List<CdcTransferEntity> cdcTransferEntities = sdsFunctionMapper.selectTransferLocInfoByParam(episodeId, mapParam);
                        if (CommonUtil.isNotEmpty(cdcTransferEntities)) {
                            resultVal = DateUtil.format(cdcTransferEntities.get(0).getTranDate(), "yyyy-MM-dd HH:mm:ss");
                        }
                    }
                    break;
                case "OutDeptDate":
                    //离开某科室日期时间
                    if (!StringUtils.isEmpty(dicId)) {
                        Map<String, String> mapParam = handleDicMatchParam(dicId, 3);
                        List<CdcTransferEntity> cdcTransferEntities = sdsFunctionMapper.selectTransferLocInfoByParam(episodeId, mapParam);
                        if (CommonUtil.isNotEmpty(cdcTransferEntities)) {
                            resultVal = DateUtil.format(cdcTransferEntities.get(0).getFromDate(), "yyyy-MM-dd HH:mm:ss");
                        }
                    }
                    break;
                case "InHosTrans":
                    //到院交通工具,默认私家车
                    resultVal = "私家车";
                    Wrapper<CdcOrdexecEntity> ordexecEntityWrapper = new EntityWrapper<>();
                    ordexecEntityWrapper.eq("episode_id", episodeId).eq("is_active", 1);
                    List<CdcOrdexecEntity> cdcOrdexecEntities = cdcOrdexecService.selectList(ordexecEntityWrapper);
                    for (CdcOrdexecEntity cdcOrdexecEntity : cdcOrdexecEntities) {
                        CdcOrdmastEntity ordmastEntity = cdcOrdmastService.selectById(cdcOrdexecEntity.getOrderMastId());
                        if (!CommonUtil.isEmpty(ordmastEntity)) {
                            if (ordmastEntity.getDescription().contains("救护车")) {
                                resultVal = "救护车";
                                break;
                            }
                        }
                    }
                    break;
                case "admYear":
                    // 通过就诊号获取患者就诊信息
                    Map<String, Object> episodeInfo1 = sdsFunctionMapper.getPatientInfo(episodeId);
                    if (CommonUtil.isNotEmpty(episodeInfo1.get("admdate"))) {
                        String admDate = episodeInfo1.get("admdate").toString();
                        resultVal = admDate.substring(0, 4);
                    }
                    break;
                case "admQuarter":
                    // 通过就诊号获取患者就诊信息
                    Map<String, Object> episodeInfo2 = sdsFunctionMapper.getPatientInfo(episodeId);
                    if (CommonUtil.isNotEmpty(episodeInfo2.get("admdate"))) {
                        String admDate = episodeInfo2.get("admdate").toString();
                        System.out.println(admDate.substring(5, 7));
                        Integer month = Integer.valueOf(admDate.substring(5, 7));
                        //月份对应季度
                        int quarter = (month + 2) / 3;
                        switch (quarter) {
                            case 1:
                                resultVal = "一";
                                break;
                            case 2:
                                resultVal = "二";
                                break;
                            case 3:
                                resultVal = "三";
                                break;
                            case 4:
                                resultVal = "四";
                                break;
                        }
                    }
                    break;
                case "admMonth":
                    // 通过就诊号获取患者就诊信息
                    Map<String, Object> episodeInfo3 = sdsFunctionMapper.getPatientInfo(episodeId);
                    if (CommonUtil.isNotEmpty(episodeInfo3.get("admdate"))) {
                        String admDate = episodeInfo3.get("admdate").toString();
                        resultVal = admDate.substring(5, 7);
                    }
                    break;
                default:
                    // 通过就诊号获取患者就诊信息
                    Map<String, Object> episodeInfo = sdsFunctionMapper.getPatientInfo(episodeId);
                    resultVal = ObjectUtil.toString(episodeInfo.get(sourceCode));
                    //对科室处理，去掉短横线和括号
                    if (CommonUtil.equals(sourceCode, "admloc")) {
                        if (CommonUtil.contains(resultVal, "-")) {
                            resultVal = resultVal.split("-")[1];
                        }
                        resultVal = resultVal.replace("(", "");
                        resultVal = resultVal.replace(")", "");
                        resultVal = resultVal.replace("/", "");
                    }
                    break;
            }
            if (CommonUtil.isNotEmpty(resultVal)) {
                List<Map<String, Object>> result = new ArrayList<>();
                Map<String, Object> map = new HashMap<>();
                map.put(sourceCode, resultVal);
                map.put("id", episodeId);
                result.add(map);
                resultList.add(result);
            }
        }
        return resultList;
    }

    /**
     * 获取病人HIS数据-医嘱信息
     */
    public Object Ordexec(Long episodeId, Long datasourceId, Integer currentTime, Long dicId, Long valueTime) {
        List<List<Map<String, Object>>> resultList = new ArrayList<>();
        SdsStandSourceEntity source = sdsStandSourceMapper.selectById(datasourceId);
        if (!StringUtils.isEmpty(source)) {
            String sourceCode = source.getSourceCode();
            // 采集时机, 获取取值条件
            String sqlStr = this.calcGetExecTiming(episodeId, valueTime);
            if (!StringUtils.isEmpty(dicId)) {
                // 查询标准项关联医嘱
                List<Long> ordMastList = sdsStandDicMatchMapper.selectMatchOrderId(dicId);
                // 查找子节点关联医嘱
                //查找子节点
                List<Long> dicChildrenIds = sdsStandDicService.getRootChildren(dicId);
                for (Long dicChildrenId : dicChildrenIds) {
                    ordMastList.addAll(sdsStandDicMatchMapper.selectMatchOrderId(dicChildrenId));
                }
                if (ordMastList.isEmpty()) {
                    return resultList;
                }
                // 去重
                Set<Long> ordMastSet = new HashSet(ordMastList);
                ordMastList = new ArrayList(ordMastSet);
                List<Map<String, Object>> execList = sdsFunctionMapper.selectOrdExec(episodeId, null, ordMastList, sqlStr);
                if (!execList.isEmpty()) {
                    resultList.add(execList);
                }
            }
        }
        return resultList;
    }

    /**
     * 获获取病人HIS数据-诊断信息
     */
    public Object Diagnosis(Long episodeId, Long datasourceId, Integer currentTime, Long dicId, Long valueTime) {
        List<List<Map<String, Object>>> resultList = new ArrayList<>();
        Object resultVal = "";
        SdsStandSourceEntity source = sdsStandSourceMapper.selectById(datasourceId);
        if (!StringUtils.isEmpty(source)) {
            List<Map<String, Object>> result = new ArrayList<>();
            String sourceCode = source.getSourceCode();
            CdcDictionaryEntity diagSource = new CdcDictionaryEntity();
            if ("Quantity".equals(sourceCode) || "DiagDate".equals(sourceCode)) {
                //质控：诊断来源-临床
                diagSource = dictionaryService.getMatchCtDic("SDS", "SDMatchCdcDic", "C");
            } else {
                //上报：诊断来源-编目信息
                diagSource = dictionaryService.getMatchCtDic("SDS", "SDMatchCdcDic", "F");
            }
            List<CdcDiagnosisEntity> diagnosisEntities = new ArrayList<>();
            if (!StringUtils.isEmpty(dicId)) {
                //配有标准字典根据对照参数取值
                //有子节点需取所有子节点的值
                Map<String, String> mapParam = handleDicMatchParam(dicId, 2);
                List<CdcDiagnosisEntity> cdcDiagnosisEntities = sdsFunctionMapper.selectDiagnosisInfoByParam(episodeId, diagSource.getId(), mapParam);
                if (cdcDiagnosisEntities.isEmpty()) {
                    //有子节点需取所有子节点的值
                    List<Long> dicIds = sdsStandDicService.getRootChildren(dicId);
                    for (Long id : dicIds) {
                        Map<String, String> mapParamChildren = handleDicMatchParam(id, 2);
                        List<CdcDiagnosisEntity> cdcDiagnosisChildrenEntities = sdsFunctionMapper.selectDiagnosisInfoByParam(episodeId, diagSource.getId(), mapParamChildren);
                        if (!cdcDiagnosisChildrenEntities.isEmpty()) {
                            diagnosisEntities.addAll(cdcDiagnosisChildrenEntities);
                            break;
                        }
                    }
                } else {
                    diagnosisEntities.addAll(cdcDiagnosisEntities);
                }
            } else {
                //只配置数据源
                diagnosisEntities = sdsFunctionMapper.selectDiagnosisInfoByParam(episodeId, diagSource.getId(), new HashMap<>());
            }
            if ("Quantity".equals(sourceCode)) {
                resultVal = diagnosisEntities.size();
                Map<String, Object> map = new HashMap<>();
                map.put(sourceCode, resultVal);
                result.add(map);
            } else if ("DiagDate".equals(sourceCode)) {
                // 诊断时间
                Object objectId = "";
                for (CdcDiagnosisEntity cdcDiagnosisEntity : diagnosisEntities) {
                    Date diagDate = cdcDiagnosisEntity.getDiagDate();
                    Long diagnosisId = cdcDiagnosisEntity.getId();
                    if (!StringUtils.isEmpty(diagDate)) {
                        resultVal = DateUtil.getTime(diagDate);
                        objectId = Long.toString(diagnosisId);
                        break;
                    }
                }
                Map<String, Object> map = new HashMap<>();
                map.put(sourceCode, resultVal);
                map.put("id", objectId);
                result.add(map);
            } else {
                String resultStr = "";
                Object objectId = "";
                for (CdcDiagnosisEntity cdcDiagnosisEntity : diagnosisEntities) {
                    String icd10 = cdcDiagnosisEntity.getIcd10();
                    //主诊断ICD-10四位临床扩展编码与名称
                    if (Objects.equals("M4DICD10", sourceCode) || Objects.equals("OTH4DICD10", sourceCode)) {
                        if (Objects.equals("M4DICD10", sourceCode) && !Objects.equals(1, cdcDiagnosisEntity.getIsMain())) {
                            continue;
                        }
                        objectId = cdcDiagnosisEntity.getId().toString();
                        //主要诊断ICD-10四位亚目编码与名称
                        if (icd10.length() > 4) {
                            resultStr = icd10.substring(0, 5);
                        }
                        String lastChar = resultStr.substring(resultStr.length() - 1);
                        if ("x".equals(lastChar)) {
                            resultStr = resultStr.substring(0, resultStr.length() - 1);
                        }
                        lastChar = resultStr.substring(resultStr.length() - 1);
                        if (".".equals(lastChar)) {
                            resultStr = resultStr.substring(0, resultStr.length() - 1);
                        }
                    } else if (Objects.equals("M6DICD10", sourceCode) || Objects.equals("OTH6DICD10", sourceCode)) {
                        if (Objects.equals("M6DICD10", sourceCode) && !Objects.equals(1, cdcDiagnosisEntity.getIsMain())) {
                            continue;
                        }
                        objectId = cdcDiagnosisEntity.getId().toString();
                        //主要诊断ICD-10六位临床扩展编码与名称
                        String substring = "";
                        if (icd10.length() >= 8) {
                            substring = icd10.substring(7, 8);
                        }
                        if (Objects.equals("x", substring) && icd10.length() >= 11) {
                            resultStr = icd10.substring(0, 11);
                        } else if (!Objects.equals("x", substring) && icd10.length() >= 7) {
                            resultStr = icd10.substring(0, 7);
                        }
                    } else if (Objects.equals("MOTH4ICD10", sourceCode)) {
                        if (!Objects.equals(1, cdcDiagnosisEntity.getIsMain()) && !cdcDiagnosisEntity.getXcode().split("\\|\\|")[2].equals("1")) {
                            continue;
                        }
                        objectId = cdcDiagnosisEntity.getId().toString();
                        //ICD-10四位亚目编码与名称
                        if (icd10.length() > 4) {
                            resultStr = icd10.substring(0, 5);
                        }
                        String lastChar = resultStr.substring(resultStr.length() - 1);
                        if ("x".equals(lastChar)) {
                            resultStr = resultStr.substring(0, resultStr.length() - 1);
                        }
                        lastChar = resultStr.substring(resultStr.length() - 1);
                        if (".".equals(lastChar)) {
                            resultStr = resultStr.substring(0, resultStr.length() - 1);
                        }
                    } else if (Objects.equals("AllDiagDesc", sourceCode)) {
                        resultStr += "," + cdcDiagnosisEntity.getDescription();
                    } else if (Objects.equals("OthDiagCount", sourceCode)) {
                        if (!Objects.equals(1, cdcDiagnosisEntity.getIsMain())) {
                            resultStr = String.valueOf(diagnosisEntities.size() - 1);
                        }
                    } else if (sourceCode.contains("OthDiagICDDesc")) {
                        String idx = sourceCode.split("_")[1];
                        String ndx = cdcDiagnosisEntity.getXcode().split("\\|\\|")[2];
                        if (Objects.equals(idx, ndx)) {
                            resultStr = cdcDiagnosisEntity.getIcd10() + " " + cdcDiagnosisEntity.getDescription();
                            objectId = cdcDiagnosisEntity.getId().toString();
                        }
                    } else if (Objects.equals("M4DICDDESC", sourceCode)) {
                        if (!Objects.equals(1, cdcDiagnosisEntity.getIsMain())) {
                            continue;
                        }
                        objectId = cdcDiagnosisEntity.getId().toString();
                        resultStr = cdcDiagnosisEntity.getIcd10() + " " + cdcDiagnosisEntity.getDescription();
                    }
                    Map<String, Object> map = new HashMap<>();
                    map.put(sourceCode, resultStr);
                    map.put("id", objectId);
                    result.add(map);
                }
            }
            if (result.size() != 0) {
                resultList.add(result);
            }
        }
        return resultList;
    }

    /**
     * 获取病人电子病历-住院病程信息
     * 返回emrID
     */
    public Object EmrInfo(Long episodeId, Long datasourceId, Integer currentTime, Long dicId, Long valueTime) {
        List<List<Map<String, Object>>> resultList = new ArrayList<>();
        SdsStandSourceEntity source = sdsStandSourceMapper.selectById(datasourceId);
        if (!StringUtils.isEmpty(source)) {
            Map param = new HashMap();
            param.put("episodeId", episodeId);
            String sqlStr = calcGetTimingForEmr(episodeId, valueTime);
            // 查询标准项目
            if (CommonUtil.isNotEmpty(dicId)) {
                SdsStandDicEntity standDic = sdsStandDicMapper.selectById(dicId);
                if (CommonUtil.isNotEmpty(standDic.getParentId())) {
                    SdsStandDicEntity parentDic = sdsStandDicMapper.selectById(standDic.getParentId());
                    param.put("title", parentDic.getName());
                }
                param.put("subTitle", standDic.getName());
            }
            List<Map<String, Object>> emrList = sdsFunctionMapper.selectEmrList(param, sqlStr);
            if (CommonUtil.isNotEmpty(emrList)) {
                resultList.add(emrList);
            }
        }
        return resultList;
    }

    /**
     * 获取病人电子病历-结构化数据
     * 返回emrID
     */
    public Object EmrStructInfo(Long episodeId, Long datasourceId, Integer currentTime, Long dicId, Long valueTime) {
        List<List<Map<String, Object>>> resultList = new ArrayList<>();
        Object resultVal = "";

        SdsStandSourceEntity source = sdsStandSourceMapper.selectById(datasourceId);
        String sourceCode = source.getSourceCode();
        if (!StringUtils.isEmpty(dicId)) {
            SdsStandDicEntity dicEntity = sdsStandDicMapper.selectById(dicId);
            //查找关联病历子标题
            Map<String, Object> param = new HashMap<String, Object>();
            //查找标准字典的父级：症状、体征、现病史。。。
            Long parentId = dicEntity.getParentId();
            // 查询标准项所有关联医嘱
            param.put("dicId", parentId);
            List<String> subTitles = sdsStandDicMatchMapper.selectEmrSubTitle(param);
            if (!subTitles.isEmpty()) {
                List<CdcBsEmrStructEntity> emrStructs = sdsFunctionMapper.selectEmrStructInfoByParam(episodeId, subTitles);
                if (null != emrStructs && emrStructs.size() > 0) {
                    //查找标准字典关联的对照参数
                    List<SdsStandDicMatchParamEntity> dicMatchParamEntities = sdsStandDicMatchParamMapper.selectList(new EntityWrapper<SdsStandDicMatchParamEntity>()
                            .eq("dic_id", dicId));
                    if (null != dicMatchParamEntities && dicMatchParamEntities.size() > 0) {
                        List<Map<String, Object>> result = new ArrayList<>();
                        c:
                        for (CdcBsEmrStructEntity emrStruct : emrStructs) {
                            JSONArray jsonArray = JSONArray.parseArray(emrStruct.getEmrNlpResult());
                            String objectId = emrStruct.getEmrId().toString();
                            if (jsonArray.size() > 0) {
                                a:
                                for (int i = 0; i < jsonArray.size(); i++) {
                                    JSONObject jsonObject = jsonArray.getJSONObject(i);
                                    b:
                                    for (SdsStandDicMatchParamEntity sdsStandDicMatchParam : dicMatchParamEntities) {
                                        //目前没有排除
                                        String compareContent = sdsStandDicMatchParam.getCompareContent();
                                        if (compareContent.contains(",")) {
                                            //eg:皮肤瘙痒#level:加重,day_time:夜间
                                            //同时满足
                                            String[] split = compareContent.split(",");
                                            for (String s : split) {
                                                if (s.contains("#")) {
                                                    String[] split1 = s.split("#");
                                                    String name = split1[0];
                                                    String nlpValue = split1[1];
                                                    if (!CommonUtil.contains(jsonObject.get("name"), name)&&!CommonUtil.equals(jsonObject.get("type"), name)) {
                                                        continue b;
                                                    }
                                                    if (nlpValue.contains(":")) {
                                                        String[] split2 = nlpValue.split(":");
                                                        if (!CommonUtil.contains(jsonObject.getJSONObject(split2[0]).get("value"), split2[1]) && !CommonUtil.contains(jsonObject.getJSONObject(split2[0]).get("name"), split2[1])) {
                                                            continue b;
                                                        }
                                                    }
                                                } else {
                                                    if (s.contains(":")) {
                                                        String[] split1 = s.split(":");
                                                        if (!CommonUtil.contains(jsonObject.getJSONObject(split1[0]).getString("value"), split1[1]) && !CommonUtil.contains(jsonObject.getJSONObject(split1[0]).getString("name"), split1[1])) {
                                                            continue b;
                                                        }
                                                    }
                                                }
                                            }
                                            //都满足:返回EmrId，退出循环
                                            //resultVal = emrStruct.getEmrId();
                                            //都满足:返回true，退出循环
                                            Map<String, Object> map = new HashMap<>();
                                            map.put(sourceCode, jsonObject.get("name"));
                                            map.put("id", objectId);
                                            result.add(map);
                                            break c;
                                        } else {
                                            //eg:呼吸困难#level:加重
                                            if (compareContent.contains("#")) {
                                                String[] split = compareContent.split("#");
                                                String name = split[0];
                                                String nlpValue = split[1];
                                                if (!CommonUtil.contains(jsonObject.get("name"), name)&&!CommonUtil.equals(jsonObject.get("type"), name)) {
                                                    continue b;
                                                }
                                                String objResult = jsonObject.getString("name");
                                                if (nlpValue.contains(":")) {
                                                    String[] split2 = nlpValue.split(":");
                                                    if (!split2[1].equals(jsonObject.get(split2[0]))) {
                                                        continue b;
                                                    }
                                                } else {
                                                    objResult = jsonObject.getJSONObject(nlpValue).getString("value");
                                                    if (CommonUtil.isEmpty(objResult)) {
                                                        objResult = jsonObject.getJSONObject(nlpValue).getString("name");
                                                    }
                                                }
                                                //满足一个:返回EmrId，退出循环
                                                //resultVal = emrStruct.getEmrId();
                                                //满足一个:返回true，退出循环
                                                Map<String, Object> map = new HashMap<>();
                                                map.put(sourceCode, objResult);
                                                map.put("id", objectId);
                                                result.add(map);
                                                break c;
                                            } else {
                                                //eg:level:加重
                                                if (compareContent.contains(":")) {
                                                    String[] split = compareContent.split(":");
                                                    if (!split[1].equals(jsonObject.get(split[0]))) {
                                                        continue b;
                                                    }
                                                    //满足一个:返回EmrId，退出循环
                                                    //resultVal = emrStruct.getEmrId();
                                                    //满足一个:返回true，退出循环
                                                    String objResult = jsonObject.getString("name");
                                                    Map<String, Object> map = new HashMap<>();
                                                    map.put(sourceCode, objResult);
                                                    map.put("id", objectId);
                                                    result.add(map);
                                                    break c;
                                                } else {
                                                    //eg:发热
                                                    if (!CommonUtil.contains(jsonObject.get("name"), compareContent)) {
                                                        continue b;
                                                    }
                                                    //满足一个:返回EmrId，退出循环
                                                    //resultVal = emrStruct.getEmrId();
                                                    //满足一个:返回true，退出循环
                                                    String objResult = jsonObject.getString("name");
                                                    Map<String, Object> map = new HashMap<>();
                                                    map.put(sourceCode, objResult);
                                                    map.put("id", objectId);
                                                    result.add(map);
                                                    break c;
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                        if (CommonUtil.isNotEmpty(result)) {
                            resultList.add(result);
                        }
                    }
                }
            }
        } else { // 无标准字典配置
            String sourceDesc = source.getSourceDesc();
            List<CdcBsEmrStructEntity> nlpResults = sdsFunctionMapper.selectEmrNlpResult(episodeId, sourceDesc);
            List<Map<String, Object>> result = new ArrayList<>();
            for (CdcBsEmrStructEntity nlpResult : nlpResults) {
                Map<String, Object> map = new HashMap<>();
                map.put(sourceCode, nlpResult.getEmrNlpResult());
                map.put("id", nlpResult.getEmrId());
                result.add(map);
            }
            if (CommonUtil.isNotEmpty(result)) {
                resultList.add(result);
            }
        }
        return resultList;
    }

    /**
     * 获取病人电子病历-住病案首页基本信息
     */
    public Object EprBaseInfo(Long episodeId, Long datasourceId, Integer currentTime, Long dicId, Long valueTime) {
        List<List<Map<String, Object>>> resultList = new ArrayList<>();
        Object resultVal = "";
        Object objectId = "";

        SdsStandSourceEntity source = sdsStandSourceMapper.selectById(datasourceId);
        List<Map<String, Object>> result = new ArrayList<>();
        if (!StringUtils.isEmpty(source)) {
            String sourceCode = source.getSourceCode();
            resultVal = sdsFunctionMapper.selectEprBaseInfo(episodeId, sourceCode);
            objectId = sdsFunctionMapper.selectEprBaseInfoObjectId(episodeId, sourceCode);
            if (source.getSourceDesc().contains("31天")) {
                if (((String) resultVal).contains("有")) {
                    resultVal = "是";
                } else {
                    resultVal = "";
                }
            }
            if (((String) resultVal).contains("(")) {
                resultVal = ((String) resultVal).split("\\(")[0];
            }
            if (CommonUtil.isNotEmpty(resultVal)) {
                Map<String, Object> map = new HashMap<>();
                map.put(sourceCode, resultVal);
                map.put("id", objectId);
                result.add(map);
            }
        }
        if (CommonUtil.isNotEmpty(result)) {
            resultList.add(result);
        }
        return resultList;
    }

    /**
     * 获取病人电子病历-住病案首页费用信息
     */
    public Object EprFeeInfo(Long episodeId, Long datasourceId, Integer currentTime, Long dicId, Long valueTime) {
        List<List<Map<String, Object>>> resultList = new ArrayList<>();
        Object resultVal = "";

        SdsStandSourceEntity source = sdsStandSourceMapper.selectById(datasourceId);
        List<Map<String, Object>> result = new ArrayList<>();
        if (!StringUtils.isEmpty(source)) {
            String sourceCode = source.getSourceCode();
            Map param = new HashMap<>();
            param.put("episodeId", episodeId);
            Map<Object, Object> feeMap = sdsFunctionMapper.getFeeByType(param);
            if (CommonUtil.isNotEmpty(feeMap)) {
                if (CommonUtil.isNotEmpty(feeMap.get(sourceCode))) {
                    String feeValue = feeMap.get(sourceCode).toString();
                    //处理精度，小数点后两位
                    DecimalFormat df = new DecimalFormat("0.00");
                    resultVal = df.format(Double.parseDouble(feeValue));
                    if (CommonUtil.isNotEmpty(resultVal)) {
                        Map<String, Object> map = new HashMap<>();
                        map.put(sourceCode, resultVal);
                        map.put("id", "0");
                        result.add(map);
                    }
                }
            }
        }
        if (CommonUtil.isNotEmpty(result)) {
            resultList.add(result);
        }
        return resultList;
    }

    /**
     * 获取病人电子病历-病案首页手术信息
     */
    public Object EmrOperInfo(Long episodeId, Long datasourceId, Integer currentTime, Long dicId, Long valueTime) {
        List<List<Map<String, Object>>> resultList = new ArrayList<>();
        SdsStandSourceEntity source = sdsStandSourceMapper.selectById(datasourceId);
        if (!StringUtils.isEmpty(source)) {
            String sourceCode = source.getSourceCode();
            //数据来源:病案编目
            //根据数据中心字典对照获取病案编目
            CdcDictionaryEntity surgSource = dictionaryService.getMatchCtDic("SDS", "SDMatchCdcDic", "F1");
            List<CdcSurgeryEntity> surgeryEntities = new ArrayList<>();
            if (!StringUtils.isEmpty(dicId)) {
                //配有标准字典根据对照参数取值
                Map<String, String> mapParam = handleDicMatchParam(dicId, 1);
                //查询病案编目手术信息
                surgeryEntities = sdsFunctionMapper.selectSurgeryInfoByParam(episodeId, surgSource.getId(), mapParam);
            } else {
                //只配置数据源
                surgeryEntities = sdsFunctionMapper.selectSurgeryInfoByParam(episodeId, surgSource.getId(), null);
            }
            String resultStr = "";
            List<Map<String, Object>> result = new ArrayList<>();
            // 重新按照xcode排序
            surgeryEntities = surgeryEntities.stream().sorted(Comparator.comparing(cdcSurgeryEntity -> cdcSurgeryEntity.getXcode())).collect(Collectors.toList());
            if (null != surgeryEntities && surgeryEntities.size() > 0) {
                //获取编目手术 (第一手术默认为主手术)
                CdcSurgeryEntity cdcSurgeryEntity = surgeryEntities.get(0);
                String code = cdcSurgeryEntity.getCode();
                String ObjectId = cdcSurgeryEntity.getId().toString();
                if (Objects.equals("M4OCM3", sourceCode)) {
                    //主要手术操作栏中提取ICD-9-CM-3四位亚目编码与名称
                    if (code.length() > 4) {
                        resultStr = code.substring(0, 5);
                    }
                    String lastChar = resultStr.substring(resultStr.length() - 1);
                    if ("x".equals(lastChar)) {
                        resultStr = resultStr.substring(0, resultStr.length() - 1);
                    }
                    lastChar = resultStr.substring(resultStr.length() - 1);
                    if (".".equals(lastChar)) {
                        resultStr = resultStr.substring(0, resultStr.length() - 1);
                    }
                    Map<String, Object> map = new HashMap<>();
                    map.put("code", code);
                    map.put(sourceCode, resultStr);
                    map.put("id", ObjectId);
                    result.add(map);
                } else if (Objects.equals("M6OCM3", sourceCode)) {
                    //主要手术操作栏中提取ICD-9-CM-3六位临床扩展编码与名称
                    String substring = "";
                    if (code.length() >= 8) {
                        substring = code.substring(7, 8);
                    }
                    if (Objects.equals("x", substring) && code.length() >= 11) {
                        resultStr = code.substring(0, 11);
                    } else if (code.length() >= 7) {
                        resultStr = code.substring(0, 7);
                    }
                    Map<String, Object> map = new HashMap<>();
                    map.put(sourceCode, resultStr);
                    map.put("id", ObjectId);
                    result.add(map);
                } else if (Objects.equals("OTH4OCM3", sourceCode)) {
                    for (CdcSurgeryEntity surgeryEntity : surgeryEntities) {
                        Map<String, Object> map = new HashMap<>();
                        String allCode = surgeryEntity.getCode();
                        String objectId = surgeryEntity.getId().toString();
                        //主要手术操作栏中提取ICD-9-CM-3四位亚目编码与名称
                        if (allCode.length() > 4) {
                            resultStr = allCode.substring(0, 5);
                        }
                        String lastChar = resultStr.substring(resultStr.length() - 1);
                        if ("x".equals(lastChar)) {
                            resultStr = resultStr.substring(0, resultStr.length() - 1);
                        }
                        lastChar = resultStr.substring(resultStr.length() - 1);
                        if (".".equals(lastChar)) {
                            resultStr = resultStr.substring(0, resultStr.length() - 1);
                        }
                        map.put(sourceCode, resultStr);
                        map.put("id", objectId);
                        result.add(map);
                    }
                } else if (Objects.equals("OTH6OCM3", sourceCode)) {
                    for (CdcSurgeryEntity surgeryEntity : surgeryEntities) {
                        Map<String, Object> map = new HashMap<>();
                        String allCode = surgeryEntity.getCode();
                        String objectId = surgeryEntity.getId().toString();
                        //主要手术操作栏中提取ICD-9-CM-3六位临床扩展编码与名称
                        String substring = "";
                        if (allCode.length() >= 8) {
                            substring = allCode.substring(7, 8);
                        }
                        if (Objects.equals("x", substring) && allCode.length() >= 11) {
                            resultStr = allCode.substring(0, 11);
                        } else if (allCode.length() >= 7) {
                            resultStr = allCode.substring(0, 7);
                        }
                        map.put(sourceCode, resultStr);
                        map.put("id", objectId);
                        result.add(map);
                    }
                } else {
                    if (CommonUtil.equals("startDate", sourceCode)) {
                        resultStr = DateUtil.getTime(cdcSurgeryEntity.getStartDate());
                    } else if (CommonUtil.equals("endDate", sourceCode)) {
                        resultStr = DateUtil.getTime(cdcSurgeryEntity.getEndDate());
                    } else if (CommonUtil.equals("LoseBlood", sourceCode)) {
                        resultStr = cdcSurgeryEntity.getBloodLose();
                    } else if (CommonUtil.equals("healType", sourceCode)) {
                        CdcDictionaryEntity cdcDictionaryEntity = cdcDictionaryService.selectById(cdcSurgeryEntity.getBusSurgHealId());
                        if (!StringUtils.isEmpty(cdcDictionaryEntity)) {
                            resultStr = cdcDictionaryEntity.getDescription();
                        }
                    } else if (CommonUtil.equals("GotBlood", sourceCode)) {
                        resultStr = cdcSurgeryEntity.getBloodGet();
                    } else if (CommonUtil.equals("inciLevel", sourceCode)) {
                        CdcDictionaryEntity cdcDictionaryEntity = cdcDictionaryService.selectById(cdcSurgeryEntity.getBusSurgInciId());
                        if (!StringUtils.isEmpty(cdcDictionaryEntity)) {
                            resultStr = cdcDictionaryEntity.getDescription();
                        }
                    } else if (CommonUtil.equals("inciCount", sourceCode)) {
                        resultStr = cdcSurgeryEntity.getInciCount().toString();
                    } else if (CommonUtil.equals("anesType", sourceCode)) {
                        CdcDictionaryEntity cdcDictionaryEntity = cdcDictionaryService.selectById(cdcSurgeryEntity.getBusSurgAnesId());
                        if (!StringUtils.isEmpty(cdcDictionaryEntity)) {
                            resultStr = cdcDictionaryEntity.getDescription();
                        }
                    } else if (CommonUtil.equals("AllOperDesc", sourceCode)) {
                        for (CdcSurgeryEntity surgeryEntity : surgeryEntities) {
                            resultStr += surgeryEntity.getDescription() + ",";
                        }
                    }
                    Map<String, Object> map = new HashMap<>();
                    map.put(sourceCode, resultStr);
                    map.put("id", ObjectId);
                    result.add(map);
                }
                if (result.size() != 0) {
                    resultList.add(result);
                }
            }
        }
        return resultList;
    }

    /**
     * 获取病人检查系统信息
     */
    public Object Ris(Long episodeId, Long datasourceId, Integer currentTime, Long dicId, Long valueTime) {
        List<List<Map<String, Object>>> resultList = new ArrayList<>();
        SdsStandSourceEntity source = sdsStandSourceMapper.selectById(datasourceId);
        if (!StringUtils.isEmpty(source)) {
            String sourceCode = source.getSourceCode();
            // 采集时机, 获取取值条件
            String sqlStr = this.calcGetExecTiming(episodeId, valueTime);
            if (!StringUtils.isEmpty(dicId)) {
                // 查询标准项关联医嘱
                List<Long> ordMastList = sdsStandDicMatchMapper.selectMatchOrderId(dicId);
                // 查找子节点关联医嘱
                //查找子节点
                List<Long> dicChildrenIds = sdsStandDicService.getRootChildren(dicId);
                for (Long dicChildrenId : dicChildrenIds) {
                    ordMastList.addAll(sdsStandDicMatchMapper.selectMatchOrderId(dicChildrenId));
                }
                if (ordMastList.isEmpty()) {
                    return resultList;
                }
                // 去重
                Set<Long> ordMastSet = new HashSet(ordMastList);
                ordMastList = new ArrayList(ordMastSet);
                List<Map<String, Object>> list = sdsFunctionMapper.selectExaminate(episodeId, null, ordMastList, sqlStr);
                if (!list.isEmpty()) {
                    resultList.add(list);
                }
            } else {
                // 未配置标准项，查询患者所有检查项目
                List<Map<String, Object>> list = sdsFunctionMapper.selectExaminate(episodeId, null, new ArrayList<>(), sqlStr);
                resultList.add(list);
            }
        }
        return resultList;
    }

    /**
     * 获取病人检查-结构化数据
     *
     */
    public Object ExamStructInfo(Long episodeId, Long datasourceId, Integer currentTime, Long dicId, Long valueTime) {
        List<List<Map<String, Object>>> resultList = new ArrayList<>();
        Object resultVal = "";

        SdsStandSourceEntity source = sdsStandSourceMapper.selectById(datasourceId);
        String sourceCode = source.getSourceCode();
        if (!StringUtils.isEmpty(dicId)) {
            // 获取采集时间描述
            String getType = "";
            if (CommonUtil.isNotEmpty(valueTime)) {
                DictionaryEntity getTimingDic = dictionaryMapper.selectById(valueTime);
                getType = getTimingDic.getCode();
            }
            Wrapper wpr = new EntityWrapper<CdcBsExamStructEntity>();
            wpr.eq("episode_id", episodeId);
            // 如果采集时机为住院末次，则倒序排
            wpr.orderBy("exam_date", CommonUtil.equals(getType, "LastInHosp")?false:true);
            List<CdcBsExamStructEntity> examStructs = cdcBsExamStructMapper.selectList(wpr);
            if (null != examStructs && examStructs.size() > 0) {
                //查找标准字典关联的对照参数
                List<SdsStandDicMatchParamEntity> dicMatchParamEntities = sdsStandDicMatchParamMapper.selectList(new EntityWrapper<SdsStandDicMatchParamEntity>()
                        .eq("dic_id", dicId));
                if (null != dicMatchParamEntities && dicMatchParamEntities.size() > 0) {
                    List<Map<String, Object>> result = new ArrayList<>();
                    c:
                    for (CdcBsExamStructEntity examStruct : examStructs) {
                        String objNlpInfo = examStruct.getExamNlpResult();
                        String objectId = examStruct.getExamId().toString();
                        if (CommonUtil.equals(sourceCode, "ExamNlpDesc")) {
                            objNlpInfo = examStruct.getExamNlpDesc();
                        }
                        JSONArray jsonArray = JSONArray.parseArray(objNlpInfo);
                        if (CommonUtil.isNotEmpty(jsonArray)) {
                            a:
                            for (int i = 0; i < jsonArray.size(); i++) {
                                JSONObject jsonObject = jsonArray.getJSONObject(i);
                                b:
                                for (SdsStandDicMatchParamEntity sdsStandDicMatchParam : dicMatchParamEntities) {
                                    //目前没有排除
                                    String compareContent = sdsStandDicMatchParam.getCompareContent();
                                    if (compareContent.contains(",")) {
                                        //eg:皮肤瘙痒#level:加重,day_time:夜间
                                        //同时满足
                                        String[] split = compareContent.split(",");
                                        for (String s : split) {
                                            if (s.contains("#")) {
                                                String[] split1 = s.split("#");
                                                String name = split1[0];
                                                String nlpValue = split1[1];
                                                if (!CommonUtil.contains(jsonObject.get("name"), name)) {
                                                    continue b;
                                                }
                                                if (nlpValue.contains(":")) {
                                                    String[] split2 = nlpValue.split(":");
                                                    if (!CommonUtil.contains(jsonObject.getJSONObject(split2[0]).get("value"), split2[1]) && !CommonUtil.contains(jsonObject.getJSONObject(split2[0]).get("name"), split2[1])) {
                                                        continue b;
                                                    }
                                                }
                                            } else {
                                                if (s.contains(":")) {
                                                    String[] split1 = s.split(":");
                                                    if (!CommonUtil.contains(jsonObject.getJSONObject(split1[0]).getString("value"), split1[1]) && !CommonUtil.contains(jsonObject.getJSONObject(split1[0]).getString("name"), split1[1])) {
                                                        continue b;
                                                    }
                                                }
                                            }
                                        }
                                        //都满足:返回EmrId，退出循环
                                        //resultVal = emrStruct.getEmrId();
                                        //都满足:返回true，退出循环
                                        Map<String, Object> map = new HashMap<>();
                                        map.put(sourceCode, jsonObject.get("name"));
                                        map.put("id", objectId);
                                        result.add(map);
                                        break c;
                                    } else {
                                        //eg:呼吸困难#level:加重
                                        if (compareContent.contains("#")) {
                                            String[] split = compareContent.split("#");
                                            String name = split[0];
                                            String nlpValue = split[1];
                                            if (!CommonUtil.contains(jsonObject.get("name"), name)) {
                                                continue b;
                                            }
                                            String objResult = jsonObject.getString("name");
                                            if (nlpValue.contains(":")) {
                                                String[] split2 = nlpValue.split(":");
                                                if (!split2[1].equals(jsonObject.get(split2[0]))) {
                                                    continue b;
                                                }
                                            } else {
                                                objResult = jsonObject.getJSONObject(nlpValue).getString("value");
                                                if (CommonUtil.isEmpty(objResult)) {
                                                    objResult = jsonObject.getJSONObject(nlpValue).getString("name");
                                                }
                                            }
                                            //满足一个:返回EmrId，退出循环
                                            //resultVal = emrStruct.getEmrId();
                                            //满足一个:返回true，退出循环
                                            Map<String, Object> map = new HashMap<>();
                                            map.put(sourceCode, objResult);
                                            map.put("id", objectId);
                                            result.add(map);
                                            break c;
                                        } else {
                                            //eg:level:加重
                                            if (compareContent.contains(":")) {
                                                String[] split = compareContent.split(":");
                                                if (!split[1].equals(jsonObject.get(split[0]))) {
                                                    continue b;
                                                }
                                                //满足一个:返回EmrId，退出循环
                                                //resultVal = emrStruct.getEmrId();
                                                //满足一个:返回true，退出循环
                                                resultVal = true;
                                                break c;
                                            } else {
                                                //eg:发热
                                                if (!CommonUtil.contains(jsonObject.get("name"), compareContent)) {
                                                    continue b;
                                                }
                                                //满足一个:返回EmrId，退出循环
                                                //resultVal = emrStruct.getEmrId();
                                                //满足一个:返回true，退出循环
                                                String objResult = jsonObject.getString("name");
                                                Map<String, Object> map = new HashMap<>();
                                                map.put(sourceCode, objResult);
                                                map.put("id", objectId);
                                                result.add(map);
                                                break c;
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                    if (CommonUtil.isNotEmpty(result)) {
                        resultList.add(result);
                    }
                }
            }
        } else { // 无标准字典配置
            List<CdcBsExamStructEntity> examStructs = cdcBsExamStructMapper.selectList(new EntityWrapper<CdcBsExamStructEntity>().eq("episode_id", episodeId));
            List<Map<String, Object>> result = new ArrayList<>();
            for (CdcBsExamStructEntity examStruct : examStructs) {
                Map<String, Object> map = new HashMap<>();
                String objNlpInfo = examStruct.getExamNlpResult();
                String objectId = examStruct.getExamId().toString();
                if (CommonUtil.equals(sourceCode, "ExamNlpDesc")) {
                    objNlpInfo = examStruct.getExamNlpDesc();
                }
                map.put(sourceCode, objNlpInfo);
                map.put("id", objectId);
                result.add(map);
            }
            if (CommonUtil.isNotEmpty(result)) {
                resultList.add(result);
            }
        }
        return resultList;
    }

    /**
     * 获取病人检验系统-送检记录信息
     * 取值时机 目前支持 入院首次和末次，默认末次
     */
    public Object LisVisit(Long episodeId, Long datasourceId, Integer currentTime, Long dicId, Long valueTime) {
        List<List<Map<String, Object>>> resultList = new ArrayList<>();
        String valueTimeSql = getLabVisitValueTimeSql(episodeId, valueTime);
        SdsStandSourceEntity source = sdsStandSourceMapper.selectById(datasourceId);
        if (!StringUtils.isEmpty(source)) {
            String sourceCode = source.getSourceCode();
            if (!StringUtils.isEmpty(dicId)) {
                // 查询标准项所有关联医嘱
                List<Long> labIds = sdsStandDicMatchMapper.selectMatchOrderId(dicId);
                List<Map<String, Object>> list = new ArrayList<>();
                if (!labIds.isEmpty()) {
                    list = sdsFunctionMapper.selectLabVisit(episodeId, labIds, valueTimeSql);
                }
                if (CommonUtil.isNotEmpty(list)) {
                    resultList.add(list);
                }
            } else {
                if ("LabCollNum".equals(sourceCode)) {
                    //送检记录数量
                    List<Map<String, Object>> list = sdsFunctionMapper.selectLabVisit(episodeId, null, valueTimeSql);
                    Map<String, Object> map = new HashMap<>();
                    if (null != list && list.size() > 0) {
                        map.put(sourceCode, list.size());
                    } else {
                        map.put(sourceCode, 0);
                    }
                    list = new ArrayList<>();
                    list.add(map);
                    resultList.add(list);
                } else {
                    List<Map<String, Object>> list = sdsFunctionMapper.selectLabVisit(episodeId, null, valueTimeSql);
                    if (CommonUtil.isNotEmpty(list)) {
                        resultList.add(list);
                    }
                }
            }
        }
        return resultList;
    }

    private String getLabVisitValueTimeSql(Long episodeId, Long valueTime) {

        String sqlStr = "";
        String filterSqlByDate = "AND v.rec_date BETWEEN str_to_date('${sTime}','%Y-%m-%d %H:%i:%s') AND str_to_date('${eTime}', '%Y-%m-%d %H:%i:%s')";
        String filterSqlBySort = " ORDER BY v.rec_date ${seqType}";
        String seqType = "";
        Long tmpTime = 0L;
        String fTime = "";
        String tTime = "";

        Map<String, Object> map = new HashMap<>();
        map.put("seqType", "ASC");
        // 如果没有配置采集时机，默认入院首次
        if (CommonUtil.isEmpty(valueTime)) {
            StrSubstitutor strSubstitutor = new StrSubstitutor(map);
            sqlStr = strSubstitutor.replace(filterSqlBySort);
            return sqlStr;
        }
        // 获取采集时间描述
        DictionaryEntity getTimingDic = dictionaryMapper.selectById(valueTime);
        String getType = getTimingDic.getCode();
        // 如果采集时机包含手术，则先取手术开始、结束时间
        if (getType.contains("Oper")) {
            Wrapper<CdcSurgeryEntity> operWpr = new EntityWrapper<>();
            operWpr.eq("episode_id", episodeId).eq("is_active", 1).orderBy("start_date");
            List<CdcSurgeryEntity> operList = cdcSurgeryMapper.selectList(operWpr);
            if (operList.size() == 0) {
                return "";
            }
            // 只取首次手术
            Date startDate = DateUtil.parse("1900-01-01 00:00:00");
            Date endDate = DateUtil.parse("1900-01-01 00:00:00");
            switch (getType) {
                case "BfOper":
                    for (CdcSurgeryEntity oper : operList) {
                        if (oper.getStartDate() != null || oper.getEndDate() != null) {
                            startDate = oper.getStartDate();
                            break;
                        }
                    }
                    // 术前，默认手术前0.5-1小时
                    tmpTime = startDate.getTime();
                    fTime = DateUtil.getTime(new Date(tmpTime - 3600 * 1000));
                    tTime = DateUtil.getTime(new Date(tmpTime - 1800 * 1000));
                    sqlStr = filterSqlByDate;
                    break;
                case "InOper":
                    for (CdcSurgeryEntity oper : operList) {
                        if (oper.getStartDate() != null && oper.getEndDate() != null) {
                            startDate = oper.getStartDate();
                            endDate = oper.getEndDate();
                            break;
                        }
                    }
                    // 术中
                    fTime = DateUtil.getTime(startDate);
                    tTime = DateUtil.getTime(endDate);
                    sqlStr = filterSqlByDate;
                    break;
                case "AfOper":
                    for (CdcSurgeryEntity oper : operList) {
                        if (oper.getStartDate() != null || oper.getEndDate() != null) {
                            endDate = oper.getEndDate();
                            break;
                        }
                    }
                    // 术后，默认手术后72小时
                    tmpTime = endDate.getTime();
                    fTime = DateUtil.getTime(endDate);
                    tTime = DateUtil.getTime(new Date(tmpTime + 3 * 24 * 3600 * 1000));
                    sqlStr = filterSqlByDate;
                    break;
                case "AllOper":
                    for (CdcSurgeryEntity oper : operList) {
                        if (oper.getStartDate() != null || oper.getEndDate() != null) {
                            startDate = oper.getStartDate();
                            endDate = oper.getEndDate();
                            break;
                        }
                    }
                    //围术期
                    tmpTime = startDate.getTime();
                    fTime = DateUtil.getTime(new Date(tmpTime - 3600 * 1000));
                    tmpTime = endDate.getTime();
                    tTime = DateUtil.getTime(new Date(tmpTime + 3 * 24 * 3600 * 1000));
                    sqlStr = filterSqlByDate;
                    break;
            }
        } else {
            // 获取就诊时间
            CdcEpisodeEntity admObj = cdcEpisodeMapper.selectById(episodeId);
            Date admDate = admObj.getAdmDate();
            Date dishDate = admObj.getDishDate();
            switch (getType) {
                case "Emergency":
                    // 急诊, 默认早于入院时间
                    tmpTime = admDate.getTime();
                    fTime = DateUtil.getTime(new Date(tmpTime - 24 * 3600 * 1000));
                    tTime = DateUtil.getTime(new Date(tmpTime));
                    sqlStr = filterSqlByDate;
                    break;
                case "LastInHosp":
                    // 住院末次
                    map.put("seqType", "DESC");
                    sqlStr = filterSqlBySort;
                    break;
                case "EMR-Inhos24":
                    // 急诊/入院24小时
                    tmpTime = admDate.getTime();
                    fTime = DateUtil.getTime(admDate);
                    tTime = DateUtil.getTime(new Date(tmpTime + 24 * 3600 * 1000));
                    sqlStr = filterSqlByDate;
                    break;
                case "DurHosp":
                    // 住院期间 医嘱日期范围为住院期间
                    fTime = DateUtil.getTime(admDate);
                    tTime = DateUtil.getTime(dishDate);
                    sqlStr = filterSqlByDate;
                    break;
                default:
                    // 默认入院首次
                    map.put("seqType", "ASC");
                    sqlStr = filterSqlBySort;
                    break;
            }
        }
        map.put("sTime", fTime);
        map.put("eTime", tTime);
        StrSubstitutor strSubstitutor = new StrSubstitutor(map);
        sqlStr = strSubstitutor.replace(sqlStr);
        return sqlStr;
    }


    /**
     * 获取病人检验系统-检验报告信息
     */
    public Object LisReport(Long episodeId, Long datasourceId, Integer currentTime, Long dicId, Long valueTime) {
        List<List<Map<String, Object>>> resultList = new ArrayList<>();
        SdsStandSourceEntity source = sdsStandSourceMapper.selectById(datasourceId);
        String valueTimeSql = getLabResultValueTimeSql(episodeId, valueTime);
        if (!StringUtils.isEmpty(source)) {
            String sourceCode = source.getSourceCode();
            if (!StringUtils.isEmpty(dicId)) {
                // 查询标准项所有关联医嘱
                List<Long> labIds = sdsStandDicMatchMapper.selectMatchOrderId(dicId);
                List<Map<String, Object>> list = new ArrayList<>();
                if (!labIds.isEmpty()) {
                    list = sdsFunctionMapper.selectLabReport(episodeId, null, labIds, valueTimeSql);
                }
                if (CommonUtil.isNotEmpty(list)) {
                    resultList.add(list);
                }
            } else {
                List<Map<String, Object>> list = sdsFunctionMapper.selectLabReport(episodeId, null, null, null);
                if (CommonUtil.isNotEmpty(list)) {
                    resultList.add(list);
                }
            }
        }
        return resultList;
    }

    /**
     * 获取病人检验系统-检验结果信息
     */
    public Object LisResult(Long episodeId, Long datasourceId, Integer currentTime, Long dicId, Long valueTime) {
        List<List<Map<String, Object>>> resultList = new ArrayList<>();
        SdsStandSourceEntity source = sdsStandSourceMapper.selectById(datasourceId);
        String valueTimeSql = getLabResultValueTimeSql(episodeId, valueTime);
        if (!StringUtils.isEmpty(source)) {
            String sourceCode = source.getSourceCode();
            if (!StringUtils.isEmpty(dicId)) {
                //查找关联检查项目
                Map<String, Object> param = new HashMap<String, Object>();
                // 查询标准项所有关联医嘱
                param.put("dicId", dicId);
                List<Long> labItemIds = sdsStandDicMatchMapper.selectMatchLabIds(param);
                List<Map<String, Object>> list = new ArrayList<>();
                if (!labItemIds.isEmpty()) {
                    list = sdsFunctionMapper.getLabReportList(episodeId, null, labItemIds, valueTimeSql);
                    if (CommonUtil.isNotEmpty(list)) {
                        resultList.add(list);
                    }
                }
            }
        }
        return resultList;
    }

    /**
     * 获取病人护理系统-生命体征信息
     */
    public Object Sign(Long episodeId, Long datasourceId, Integer currentTime, Long dicId, Long valueTime) {
        List<List<Map<String, Object>>> resultList = new ArrayList<>();
        Object resultVal = "";
        Object objectId = "";
        SdsStandSourceEntity source = sdsStandSourceMapper.selectById(datasourceId);
        if (!StringUtils.isEmpty(source)) {
            String sourceCode = source.getSourceCode();
            Map param = new HashMap<>();
            param.put("episodeId", episodeId);
            param.put("signCode", sourceCode);
            param.put("sqlAsc", "asc");
            if (CommonUtil.isNotEmpty(valueTime)) {
                // 获取采集时间描述
                DictionaryEntity getTimingDic = dictionaryMapper.selectById(valueTime);
                String getType = getTimingDic.getCode();
                // 如果采集时机包含手术，则先取手术开始、结束时间
                if (getType.equals("LastInHosp")) {
                    param.put("sqlAsc", "desc");
                }
            }
            if ("childWeight".equals(sourceCode)) {
                List<CdcSignEntity> signList = sdsFunctionMapper.getSignByCodeLike(param);
                if (signList.size() > 0) {
                    CdcSignEntity sign = signList.get(0);
                    resultVal = sign.getValue();
                    objectId = sign.getId();
                }
            } else if ("childBirthDateTime".equals(sourceCode)) {
                param.put("signCode", "childWeight");
                List<CdcSignEntity> signList = sdsFunctionMapper.getSignByCodeLike(param);
                if (signList.size() > 0) {
                    CdcSignEntity sign = signList.get(0);
                    resultVal = DateUtil.getTime(sign.getCheckDate());
                    objectId = sign.getId();
                }
            } else {
                resultVal = sdsFunctionMapper.getSignByCode(param);
                objectId = sdsFunctionMapper.getSignByCodeObjectId(param);
            }
            if (CommonUtil.contains("平车卧床轮椅扶行搀扶无法测量未测", resultVal)) {
                resultVal = CdcConfigCache.me().getValueByKey("sds", "DefValForPingche", "");
            }
            List<Map<String, Object>> result = new ArrayList<>();
            Map<String, Object> map = new HashMap<>();
            map.put(sourceCode, resultVal);
            map.put("id", objectId);
            result.add(map);
            resultList.add(result);
        }
        return resultList;
    }

    /**
     * 获取护理病历信息
     */
    public Object NurRecord(Long episodeId, Long datasourceId, Integer currentTime, Long dicId, Long valueTime) {
        List<List<Map<String, Object>>> resultList = new ArrayList<>();
        SdsStandSourceEntity source = sdsStandSourceMapper.selectById(datasourceId);
        if (!StringUtils.isEmpty(source)) {
            Map param = new HashMap();
            param.put("episodeId", episodeId);
            // 查询标准项目
            if (CommonUtil.isNotEmpty(dicId)) {
                SdsStandDicEntity standDic = sdsStandDicMapper.selectById(dicId);
                if (CommonUtil.isNotEmpty(standDic.getParentId())) {
                    SdsStandDicEntity parentDic = sdsStandDicMapper.selectById(standDic.getParentId());
                    param.put("docName", parentDic.getName());
                }
                param.put("description", standDic.getName());
            }
            List<Map<String, Object>> emrList = sdsFunctionMapper.selectNurRecord(param);
            if (CommonUtil.isNotEmpty(emrList)) {
                resultList.add(emrList);
            }
        }
        return resultList;
    }

    /**
     * 获取病人手麻系统信息
     */
    public Object Operate(Long episodeId, Long datasourceId, Integer currentTime, Long dicId, Long valueTime) {
        List<List<Map<String, Object>>> resultList = new ArrayList<>();
        Object resultVal = "";
        String objectId = "";
        SdsStandSourceEntity source = sdsStandSourceMapper.selectById(datasourceId);
        if (!StringUtils.isEmpty(source)) {
            String sourceCode = source.getSourceCode();
            //数据来源:手术申请单
            //根据数据中心字典对照获取手术申请单
            CdcDictionaryEntity surgSource = dictionaryService.getMatchCtDic("SDS", "SDMatchCdcDic", "C1");
            List<CdcSurgeryEntity> surgeryEntities = new ArrayList<>();
            if (!StringUtils.isEmpty(dicId)) {
                //配有标准字典根据对照参数取值
                Map<String, String> mapParam = handleDicMatchParam(dicId, 1);
                //查询手麻手术信息
                surgeryEntities = sdsFunctionMapper.selectSurgeryInfoByParam(episodeId, surgSource.getId(), mapParam);
            } else {
                //只配置数据源
                surgeryEntities = sdsFunctionMapper.selectSurgeryInfoByParam(episodeId, surgSource.getId(), null);
            }
            if (surgeryEntities.size() > 0) {
                if ("Quantity".equals(sourceCode)) {
                    if (!StringUtils.isEmpty(valueTime)) {
                        List<CdcSurgeryEntity> cdcSurgeryEntities = calcGetOperTiming(episodeId, surgeryEntities, valueTime);
                        resultVal = cdcSurgeryEntities.size();
                    } else {
                        resultVal = surgeryEntities.size();
                    }
                } else {
                    for (CdcSurgeryEntity cdcSurgeryEntity : surgeryEntities) {
                        if (CommonUtil.equals("startDate", sourceCode)) {
                            if (CommonUtil.isNotEmpty(cdcSurgeryEntity.getStartDate())) {
                                resultVal = DateUtil.getTime(cdcSurgeryEntity.getStartDate());
                                objectId = cdcSurgeryEntity.getId().toString();
                                break;
                            }
                        } else if (CommonUtil.equals("endDate", sourceCode)) {
                            if (CommonUtil.isNotEmpty(cdcSurgeryEntity.getEndDate())) {
                                resultVal = DateUtil.getTime(cdcSurgeryEntity.getEndDate());
                                objectId = cdcSurgeryEntity.getId().toString();
                                break;
                            }
                        } else if (CommonUtil.equals("LoseBlood", sourceCode)) {
                            if (CommonUtil.isNotEmpty(cdcSurgeryEntity.getBloodLose())) {
                                resultVal = cdcSurgeryEntity.getBloodLose();
                                objectId = cdcSurgeryEntity.getId().toString();
                                break;
                            }
                        } else if (CommonUtil.equals("healType", sourceCode)) {
                            if (cdcSurgeryEntity.getBusSurgHealId() != null) {
                                CdcDictionaryEntity cdcDictionary = cdcDictionaryService.selectById(cdcSurgeryEntity.getBusSurgHealId());
                                resultVal = cdcDictionary.getDescription();
                                objectId = cdcSurgeryEntity.getId().toString();
                                break;
                            }
                        } else if (CommonUtil.equals("GotBlood", sourceCode)) {
                            resultVal = cdcSurgeryEntity.getBloodGet();
                            objectId = cdcSurgeryEntity.getId().toString();
                            break;
                        } else if (CommonUtil.equals("inciLevel", sourceCode)) {
                            if (cdcSurgeryEntity.getBusSurgInciId() != null) {
                                CdcDictionaryEntity cdcDictionary = cdcDictionaryService.selectById(cdcSurgeryEntity.getBusSurgInciId());
                                resultVal = cdcDictionary.getDescription();
                                objectId = cdcSurgeryEntity.getId().toString();
                                break;
                            }
                        } else if (CommonUtil.equals("inciCount", sourceCode)) {
                            if (cdcSurgeryEntity.getInciCount() != null) {
                                resultVal = cdcSurgeryEntity.getInciCount().toString();
                                objectId = cdcSurgeryEntity.getId().toString();
                                break;
                            }
                        } else if (CommonUtil.equals("anesType", sourceCode)) {
                            if (cdcSurgeryEntity.getBusSurgAnesId() != null) {
                                CdcDictionaryEntity cdcDictionary = cdcDictionaryService.selectById(cdcSurgeryEntity.getBusSurgAnesId());
                                resultVal = cdcDictionary.getDescription();
                                objectId = cdcSurgeryEntity.getId().toString();
                                break;
                            }
                        } else if (CommonUtil.equals("asaScore", sourceCode)) {
                            if (cdcSurgeryEntity.getAsaScore() != null) {
                                resultVal = cdcSurgeryEntity.getAsaScore();
                                objectId = cdcSurgeryEntity.getId().toString();
                                break;
                            }
                        } else if (CommonUtil.equals("IsEmergency", sourceCode)) {
                            if (cdcSurgeryEntity.getIsEmergency() != null) {
                                resultVal = cdcSurgeryEntity.getIsEmergency().toString();
                                objectId = cdcSurgeryEntity.getId().toString();
                                break;
                            }
                        } else if (CommonUtil.equals("IsReoperation", sourceCode)) {
                            //获取手麻记录中的信息
                            List<CdcSurgeryEntity> tmpCdcSurgerList = cdcSurgeryMapper.selectList(new EntityWrapper<CdcSurgeryEntity>().eq("episode_id", cdcSurgeryEntity.getEpisodeId())
                                    .ne("bus_surg_source_id", cdcSurgeryEntity.getBusSurgSourceId()));
                            int operCount = 0;
                            String objId = "";
                            for (CdcSurgeryEntity surgeryEntity : tmpCdcSurgerList) {
                                if (surgeryEntity.getStartDate() != null) {
                                    operCount++;
                                    objId += surgeryEntity.getId().toString() +",";
                                }
                            }
                            if (operCount > 1) {
                                resultVal = "1";
                                objectId = objId;
                                break;
                            } else {
                                resultVal = "0";
                            }
                        } else if (CommonUtil.equals("AllOperDesc", sourceCode)) {
                            resultVal += cdcSurgeryEntity.getDescription() + ",";
                            objectId += cdcSurgeryEntity.getId().toString() +",";
                        } else if (CommonUtil.equals("childBirthDate", sourceCode)) {
                            if (CommonUtil.isNotEmpty(cdcSurgeryEntity.getChildBirthDate())) {
                                resultVal = DateUtil.getTime(cdcSurgeryEntity.getChildBirthDate());
                                objectId = cdcSurgeryEntity.getId().toString();
                                break;
                            }
                        }
                    }
                }
            }
            List<Map<String, Object>> result = new ArrayList<>();
            if (CommonUtil.isNotEmpty(resultVal)) {
                Map<String, Object> map = new HashMap<>();
                map.put(sourceCode, resultVal);
                map.put("id", objectId);
                result.add(map);
                resultList.add(result);
            }
        }
        return resultList;
    }

    private String getLabResultValueTimeSql(Long episodeId, Long valueTime) {
        String sqlStr = "";
        String filterSqlByDate = "AND n.report_date BETWEEN str_to_date('${sTime}','%Y-%m-%d %H:%i:%s') AND str_to_date('${eTime}', '%Y-%m-%d %H:%i:%s')";
        String filterSqlBySort = " ORDER BY n.report_date ${seqType}";
        String seqType = "";
        Long tmpTime = 0L;
        String fTime = "";
        String tTime = "";

        Map<String, Object> map = new HashMap<>();
        map.put("seqType", "ASC");
        // 如果没有配置采集时机，默认入院首次
        if (CommonUtil.isEmpty(valueTime)) {
            StrSubstitutor strSubstitutor = new StrSubstitutor(map);
            sqlStr = strSubstitutor.replace(filterSqlBySort);
            return sqlStr;
        }
        // 获取采集时间描述
        DictionaryEntity getTimingDic = dictionaryMapper.selectById(valueTime);
        String getType = getTimingDic.getCode();
        // 如果采集时机包含手术，则先取手术开始、结束时间
        if (getType.contains("Oper")) {
            Wrapper<CdcSurgeryEntity> operWpr = new EntityWrapper<>();
            operWpr.eq("episode_id", episodeId).eq("is_active", 1).orderBy("start_date");
            List<CdcSurgeryEntity> operList = cdcSurgeryMapper.selectList(operWpr);
            if (operList.size() == 0) {
                return "";
            }
            // 只取首次手术
            Date startDate = DateUtil.parse("1900-01-01 00:00:00");
            Date endDate = DateUtil.parse("1900-01-01 00:00:00");
            switch (getType) {
                case "BfOper":
                    for (CdcSurgeryEntity oper : operList) {
                        if (oper.getStartDate() != null || oper.getEndDate() != null) {
                            startDate = oper.getStartDate();
                            break;
                        }
                    }
                    // 术前，默认手术前0.5-1小时
                    tmpTime = startDate.getTime();
                    fTime = DateUtil.getTime(new Date(tmpTime - 3600 * 1000));
                    tTime = DateUtil.getTime(new Date(tmpTime - 1800 * 1000));
                    sqlStr = filterSqlByDate;
                    break;
                case "InOper":
                    for (CdcSurgeryEntity oper : operList) {
                        if (oper.getStartDate() != null && oper.getEndDate() != null) {
                            startDate = oper.getStartDate();
                            endDate = oper.getEndDate();
                            break;
                        }
                    }
                    // 术中
                    fTime = DateUtil.getTime(startDate);
                    tTime = DateUtil.getTime(endDate);
                    sqlStr = filterSqlByDate;
                    break;
                case "AfOper":
                    for (CdcSurgeryEntity oper : operList) {
                        if (oper.getStartDate() != null || oper.getEndDate() != null) {
                            endDate = oper.getEndDate();
                            break;
                        }
                    }
                    // 术后，默认手术后72小时
                    tmpTime = endDate.getTime();
                    fTime = DateUtil.getTime(endDate);
                    tTime = DateUtil.getTime(new Date(tmpTime + 3 * 24 * 3600 * 1000));
                    sqlStr = filterSqlByDate;
                    break;
                case "AllOper":
                    for (CdcSurgeryEntity oper : operList) {
                        if (oper.getStartDate() != null || oper.getEndDate() != null) {
                            startDate = oper.getStartDate();
                            endDate = oper.getEndDate();
                            break;
                        }
                    }
                    //围术期
                    tmpTime = startDate.getTime();
                    fTime = DateUtil.getTime(new Date(tmpTime - 3600 * 1000));
                    tmpTime = endDate.getTime();
                    tTime = DateUtil.getTime(new Date(tmpTime + 3 * 24 * 3600 * 1000));
                    sqlStr = filterSqlByDate;
                    break;
            }
        } else {
            // 获取就诊时间
            CdcEpisodeEntity admObj = cdcEpisodeMapper.selectById(episodeId);
            Date admDate = admObj.getAdmDate();
            Date dishDate = admObj.getDishDate();
            switch (getType) {
                case "Emergency":
                    // 急诊, 默认早于入院时间
                    tmpTime = admDate.getTime();
                    fTime = DateUtil.getTime(new Date(tmpTime - 24 * 3600 * 1000));
                    tTime = DateUtil.getTime(new Date(tmpTime));
                    sqlStr = filterSqlByDate;
                    break;
                case "LastInHosp":
                    // 住院末次
                    map.put("seqType", "DESC");
                    sqlStr = filterSqlBySort;
                    break;
                case "EMR-Inhos24":
                    // 急诊/入院24小时
                    tmpTime = admDate.getTime();
                    fTime = DateUtil.getTime(admDate);
                    tTime = DateUtil.getTime(new Date(tmpTime + 24 * 3600 * 1000));
                    sqlStr = filterSqlByDate;
                    break;
                case "EMR-Inhos7day":
                    tmpTime = admDate.getTime();
                    fTime = DateUtil.getTime(admDate);
                    tTime = DateUtil.getTime(new Date(tmpTime + 24 * 3600 * 1000 * 7));
                    sqlStr = filterSqlByDate;
                    break;
                case "DurHosp":
                    // 住院期间 医嘱日期范围为住院期间
                    fTime = DateUtil.getTime(admDate);
                    tTime = DateUtil.getTime(dishDate);
                    sqlStr = filterSqlByDate;
                    break;
                default:
                    // 默认入院首次
                    map.put("seqType", "ASC");
                    sqlStr = filterSqlBySort;
                    break;
            }
        }
        map.put("sTime", fTime);
        map.put("eTime", tTime);
        StrSubstitutor strSubstitutor = new StrSubstitutor(map);
        sqlStr = strSubstitutor.replace(sqlStr);
        return sqlStr;
    }

    /**
     * 获取病人VTE系统信息
     * todo:与规则库传参不一样，需单独调用
     */
    public Object VTE(Long episodeId, Long datasourceId, Integer currentTime, Long dicId, Long valueTime, Long itemId, Long entityId) {
        List<List<Map<String, Object>>> resultList = new ArrayList<>();
        Object resultVal = "";
        SdsStandSourceEntity source = sdsStandSourceMapper.selectById(datasourceId);
        if (!StringUtils.isEmpty(source)) {
            String sourceCode = source.getSourceCode();
            // 获取HIS就诊号
            CdcEpisodeEntity paadm = cdcEpisodeMapper.selectById(episodeId);
            String patientId = paadm.getXcode();
            SdsQcentityEntity qcEntity = QcEntityCache.me().getQcEntityById(entityId);
            String abbrev = qcEntity.getAbbrev();
            if (CommonUtil.equals(abbrev, "AECOPD")) {
                String subUrl = "/api/getMZFitem?EpisodeID=";
                resultVal = this.getMZFitem(patientId, itemId, sourceCode, subUrl);
            } else if (CommonUtil.equals(abbrev, "DVT")) {
                String subUrl = "/api/getWSQitem?EpisodeID=";
                resultVal = this.getWSQAndZGWitem(patientId, itemId, sourceCode, subUrl);
            } else {
                String subUrl = "/api/getZGWYFVTEitem?EpisodeID=";
                resultVal = this.getWSQAndZGWitem(patientId, itemId, sourceCode, subUrl);
            }
            List<Map<String, Object>> result = new ArrayList<>();
            Map<String, Object> map = new HashMap<>();
            map.put(sourceCode, resultVal);
            result.add(map);
            resultList.add(result);
        }
        return resultList;
    }

    /**
     * 获取病人评估/评价信息
     */
    public Object SingleDiseaseEval(Long episodeId, Long datasourceId, Integer currentTime, Long dicId, Long valueTime) {
        List<List<Map<String, Object>>> resultList = new ArrayList<>();
        Object res = "";
        SdsStandSourceEntity source = sdsStandSourceMapper.selectById(datasourceId);
        if (!StringUtils.isEmpty(source)) {
            String sourceCode = source.getSourceCode();
            String dicEntityName = "";
            if (!StringUtils.isEmpty(dicId)) {
                SdsStandDicEntity dicEntity = sdsStandDicMapper.selectById(dicId);
                dicEntityName = dicEntity.getName();
            }
            String sqlStr = "";
            if (!StringUtils.isEmpty(valueTime)) {
                sqlStr = this.calcGetEvalTiming(valueTime);
            }
            switch (sourceCode) {
                case "Quantity":
                    //数量
                    res = sdcBusiEvaluationService.selectAssessmentQuantityNew(episodeId, dicEntityName, sqlStr);
                    break;
                case "Grade":
                    //等级
                    res = sdcBusiEvaluationService.selectAssessmentGradeNew(episodeId, dicEntityName, sqlStr);
                    break;
                case "Score":
                    //分值
                    res = sdcBusiEvaluationService.selectAssessmentScoreNew(episodeId, dicEntityName, sqlStr);
                    break;
                case "Time":
                    //时间
                    //com.dhcc.core.framework.util.DateUtil.compareDate
                    res = sdcBusiEvaluationService.selectAssessmentTimeNew(episodeId, dicEntityName, sqlStr);
                    break;
                default:
                    break;
            }
            List<Map<String, Object>> result = new ArrayList<>();
            Map<String, Object> map = new HashMap<>();
            map.put(sourceCode, res);
            result.add(map);
            resultList.add(result);
        }
        return resultList;
    }

    /**
     * 获取病人禁忌症信息
     */
    public Object SingleDiseaseContraindication(Long episodeId, Long datasourceId, Integer currentTime, Long dicId, Long valueTime) {
        List<List<Map<String, Object>>> resultList = new ArrayList<>();
        Object resultVal = "";
        SdsStandSourceEntity source = sdsStandSourceMapper.selectById(datasourceId);
        if (!StringUtils.isEmpty(source)) {
            String sourceCode = source.getSourceCode();
            if (!StringUtils.isEmpty(dicId)) {
                SdsStandDicEntity dicEntity = sdsStandDicMapper.selectById(dicId);
                ContraindicationEntity contraindicationEntity = baseContraindicationService.selectOne(new EntityWrapper<ContraindicationEntity>()
                        .eq("name", dicEntity.getName())
                        .eq("active", 1));
                if (!StringUtils.isEmpty(contraindicationEntity)) {
                    SdcBusiContraindicationEntity sdcBusiContraindicationEntity = sdcBusiContraindicationService.selectOne(new EntityWrapper<SdcBusiContraindicationEntity>()
                            .eq("episode_id", episodeId)
                            .eq("contraindication_id", contraindicationEntity.getId()));
                    if (!StringUtils.isEmpty(sdcBusiContraindicationEntity)) {
                        if ("result".equals(sourceCode)) {
                            resultVal = sdcBusiContraindicationEntity.getResult();
                        }
                    }
                }
            }
            List<Map<String, Object>> result = new ArrayList<>();
            Map<String, Object> map = new HashMap<>();
            map.put(sourceCode, resultVal);
            result.add(map);
            resultList.add(result);
        }
        return resultList;
    }

    /**
     * 获取病人入组信息
     * todo:与规则库传参不一样，需单独调用
     */
    public Object SdsIntheInfo(Long episodeId, Long datasourceId, Integer currentTime, Long dicId, Long valueTime) {
        List<List<Map<String, Object>>> ressonList = new ArrayList<>();
        Object resultVal = "";
        SdsStandSourceEntity source = sdsStandSourceMapper.selectById(datasourceId);
        if (!StringUtils.isEmpty(source)) {
            String sourceCode = source.getSourceCode();
            if ("intheReason".equals(sourceCode)) {
                // 查询入组记录
                SdsQcincaseEntity sdsQcincaseEntity = sdsQcincaseService.selectOne(new EntityWrapper<SdsQcincaseEntity>().eq("episode_id", episodeId).in("state", "I,Save,Submit"));
                Wrapper<SdsQcincaseOperlogEntity> wpr = new EntityWrapper<>();
                wpr.eq("in_case_id", sdsQcincaseEntity.getId()).eq("oper_state", "I");
                SdsQcincaseOperlogEntity sdsQcincaseOperlogEntity = sdsQcincaseOperlogService.selectOne(wpr);
                String reasonStr = sdsQcincaseOperlogEntity.getOperReason();
                String[] reasonArr = reasonStr.split(",");
                for (String ruleId : reasonArr) {
                    SdsQcentityRuleEntity rule = sdsQcentityRuleService.selectById(ruleId);
                    List<Map<String, Object>> result = new ArrayList<>();
                    Map<String, Object> map = new HashMap<>();
                    map.put("intheReason", rule.getRuleDesc());
                    result.add(map);
                    ressonList.add(result);
                }
            }
        }
        return ressonList;
    }

    private String calcGetEvalTiming(Long valueTime) {
        String res = "";
        // 如果没有配置采集时机，默认取最新一条数据
        if (CommonUtil.isEmpty(valueTime)) {
            res = "ORDER BY eval.CREATE_DATE DESC LIMIT 1";
        } else {
            DictionaryEntity getTimingDic = dictionaryMapper.selectById(valueTime);
            String getType = getTimingDic.getCode();
            if ("LastInHosp".equals(getType)) {
                // 住院末次
                res = "ORDER BY eval.CREATE_DATE DESC LIMIT 1";
            } else if ("InHosp".equals(getType)) {
                //入院首次
                res = "ORDER BY eval.CREATE_DATE ASC LIMIT 1";
            }else if ("EMR-Inhos7day".equals(getType)){
                //入院一周
                res = "ORDER BY eval.CREATE_DATE ASC LIMIT 1";
            }
        }
        return res;
    }

    private String calcGetExecTiming(Long episodeId, Long valueTime) {
        String sqlStr = "";
        String filterSqlByDate = "AND oe.bus_order_priority_id <> ${priorityId} AND (oe.first_exec_date BETWEEN str_to_date('${sTime}','%Y-%m-%d %H:%i:%s') AND str_to_date('${eTime}', '%Y-%m-%d %H:%i:%s') OR oe.start_date BETWEEN str_to_date('${sTime}','%Y-%m-%d %H:%i:%s') AND str_to_date('${eTime}', '%Y-%m-%d %H:%i:%s'))";
        String filterSqlByAsc = "AND oe.bus_order_priority_id <> ${priorityId} ORDER BY IF(ISNULL(oe.first_exec_date),1,0) ${seqType}, oe.start_date ${seqType}";
        String filterSqlByDesc = "AND oe.bus_order_priority_id <> ${priorityId} ORDER BY IF(ISNULL(oe.last_exec_date),0,1) ${seqType}, oe.start_date ${seqType}";
        String filterSqlByPriority = "AND oe.bus_order_priority_id = ${priorityId} ORDER BY oe.start_date ${seqType}";
        String filterSqlByInstruc = "AND oe.bus_order_instruc_id = ${instrucId} ORDER BY oe.start_date ${seqType}";
        String seqType = "";
        Long priorityId = 0L;
        Long instrucId = 0L;
        Long tmpTime = 0L;
        String fTime = "";
        String tTime = "";

        // 出院带药 bus_order_priority:OUT
        CdcDictionaryEntity cdcDictionaryEntity = cdcDictionaryService.queryByTypeCodeAndCode("OrdData", "bus_order_priority", "OUT");
        if (!StringUtils.isEmpty(cdcDictionaryEntity)) {
            priorityId = cdcDictionaryEntity.getId();
        }

        // 如果没有配置采集时机，默认入院首次
        if (CommonUtil.isEmpty(valueTime)) {
            Map<String, Object> map = new HashMap<>();
            map.put("seqType", "ASC");
            map.put("priorityId", priorityId);
            StrSubstitutor strSubstitutor = new StrSubstitutor(map);
            sqlStr = strSubstitutor.replace(filterSqlByAsc);
            return sqlStr;
        }
        // 获取采集时间描述
        DictionaryEntity getTimingDic = dictionaryMapper.selectById(valueTime);
        String getType = getTimingDic.getCode();
        // 如果采集时机包含手术，则先取手术开始、结束时间
        if (getType.contains("Oper")) {
            Wrapper<CdcSurgeryEntity> operWpr = new EntityWrapper<>();
            operWpr.eq("episode_id", episodeId).eq("is_active", 1).orderBy("start_date");
            List<CdcSurgeryEntity> operList = cdcSurgeryMapper.selectList(operWpr);
            if (operList.size() == 0) {
                return "";
            }
            // 只取首次手术
            Date startDate = DateUtil.parse("1900-01-01 00:00:00");
            Date endDate = DateUtil.parse("1900-01-01 00:00:00");
            switch (getType) {
                case "BfOper":
                    for (CdcSurgeryEntity oper : operList) {
                        if (oper.getStartDate() != null || oper.getEndDate() != null) {
                            startDate = oper.getStartDate();
                            break;
                        }
                    }
                    // 术前，默认手术前0.5-1小时
                    tmpTime = startDate.getTime();
                    fTime = DateUtil.getTime(new Date(tmpTime - 3600 * 1000));
                    tTime = DateUtil.getTime(new Date(tmpTime - 1800 * 1000));
                    sqlStr = filterSqlByDate;
                    break;
                case "InOper":
                    for (CdcSurgeryEntity oper : operList) {
                        if (oper.getStartDate() != null && oper.getEndDate() != null) {
                            startDate = oper.getStartDate();
                            endDate = oper.getEndDate();
                            break;
                        }
                    }
                    // 术中
                    fTime = DateUtil.getTime(startDate);
                    tTime = DateUtil.getTime(endDate);
                    sqlStr = filterSqlByDate;
                    break;
                case "AfOper":
                    for (CdcSurgeryEntity oper : operList) {
                        if (oper.getStartDate() != null || oper.getEndDate() != null) {
                            endDate = oper.getEndDate();
                            break;
                        }
                    }
                    // 术后，默认手术后72小时
                    tmpTime = endDate.getTime();
                    fTime = DateUtil.getTime(endDate);
                    tTime = DateUtil.getTime(new Date(tmpTime + 3 * 24 * 3600 * 1000));
                    sqlStr = filterSqlByDate;
                    break;
                case "AllOper":
                    for (CdcSurgeryEntity oper : operList) {
                        if (oper.getStartDate() != null || oper.getEndDate() != null) {
                            startDate = oper.getStartDate();
                            endDate = oper.getEndDate();
                            break;
                        }
                    }
                    //围术期
                    tmpTime = startDate.getTime();
                    fTime = DateUtil.getTime(new Date(tmpTime - 3600 * 1000));
                    tmpTime = endDate.getTime();
                    tTime = DateUtil.getTime(new Date(tmpTime + 3 * 24 * 3600 * 1000));
                    sqlStr = filterSqlByDate;
                    break;
                case "WithOperRoom":
                    // 带手术室 bus_order_instruc:1
                    CdcDictionaryEntity cdcDictionaryEntity2 = cdcDictionaryService.queryByTypeCodeAndCode("OrdData", "bus_order_instruc", "1");
                    if (!StringUtils.isEmpty(cdcDictionaryEntity2)) {
                        instrucId = cdcDictionaryEntity2.getId();
                    }
                    seqType = "ASC";
                    sqlStr = filterSqlByInstruc;
                    break;
            }
        } else {
            // 获取就诊时间
            CdcEpisodeEntity admObj = cdcEpisodeMapper.selectById(episodeId);
            Date admDate = admObj.getAdmDate();
            Date dishDate = admObj.getDishDate();
            switch (getType) {
                case "Emergency":
                    // 急诊, 默认早于入院时间
                    tmpTime = admDate.getTime();
                    fTime = DateUtil.getTime(new Date(tmpTime - 24 * 3600 * 1000));
                    tTime = DateUtil.getTime(new Date(tmpTime));
                    sqlStr = filterSqlByDate;
                    break;
                case "LastInHosp":
                    // 住院末次
                    seqType = "DESC";
                    sqlStr = filterSqlByDesc;
                    break;
                case "EMR-Inhos24":
                    // 急诊/入院24小时
                    tmpTime = admDate.getTime();
                    fTime = DateUtil.getTime(admDate);
                    tTime = DateUtil.getTime(new Date(tmpTime + 24 * 3600 * 1000));
                    sqlStr = filterSqlByDate;
                    break;
                case "EMR-Inhos7day":
                    // 入院一周
                    tmpTime = admDate.getTime();
                    fTime = DateUtil.getTime(admDate);
                    tTime = DateUtil.getTime(new Date(tmpTime + 24 * 3600 * 1000 * 7));
                    sqlStr = filterSqlByDate;
                    break;
                case "DishHosMedi":
                    seqType = "ASC";
                    sqlStr = filterSqlByPriority;
                    break;
                case "LongOrder":
                    // 长期医嘱 bus_order_priority:S
                    CdcDictionaryEntity cdcDictionaryEntity1 = cdcDictionaryService.queryByTypeCodeAndCode("OrdData", "bus_order_priority", "S");
                    if (!StringUtils.isEmpty(cdcDictionaryEntity1)) {
                        priorityId = cdcDictionaryEntity1.getId();
                    }
                    seqType = "ASC";
                    sqlStr = filterSqlByPriority;
                    break;
                case "DurHosp":
                    // 住院期间 医嘱日期范围为住院期间
                    fTime = DateUtil.getTime(admDate);
                    tTime = DateUtil.getTime(dishDate);
                    sqlStr = filterSqlByDate;
                    break;
                default:
                    // 默认入院首次
                    seqType = "ASC";
                    sqlStr = filterSqlByAsc;
                    break;
            }
        }
        Map<String, Object> map = new HashMap<>();
        map.put("sTime", fTime);
        map.put("eTime", tTime);
        map.put("seqType", seqType);
        map.put("priorityId", priorityId);
        map.put("instrucId", instrucId);
        StrSubstitutor strSubstitutor = new StrSubstitutor(map);
        sqlStr = strSubstitutor.replace(sqlStr);
        return sqlStr;
    }

    private List<CdcSurgeryEntity> calcGetOperTiming(Long episodeId, List<CdcSurgeryEntity> surgeryEntities, Long valueTime) {
        // 获取采集时间描述
        DictionaryEntity getTimingDic = dictionaryMapper.selectById(valueTime);
        String getType = getTimingDic.getCode();
        Date startDate = DateUtil.parse("1900-01-01 00:00:00");
        Date endDate = DateUtil.parse("1900-01-01 00:00:00");
        Long tmpTime = 0L;
        String fTime = "";
        String tTime = "";
        List<CdcSurgeryEntity> operList = new ArrayList<>();
        if (getType.contains("Oper")) {
            switch (getType) {
                case "BfOper":
                    for (CdcSurgeryEntity oper : surgeryEntities) {
                        if (oper.getStartDate() != null || oper.getEndDate() != null) {
                            startDate = oper.getStartDate();
                            break;
                        }
                    }
                    // 术前
                    operList = cdcSurgeryMapper.selectByTime(episodeId, DateUtil.getTime(startDate), null, getType);
                    break;
                case "InOper":
                    for (CdcSurgeryEntity oper : surgeryEntities) {
                        if (oper.getStartDate() != null && oper.getEndDate() != null) {
                            startDate = oper.getStartDate();
                            endDate = oper.getEndDate();
                            break;
                        }
                    }
                    // 术中
                    fTime = DateUtil.getTime(startDate);
                    tTime = DateUtil.getTime(endDate);
                    operList = cdcSurgeryMapper.selectByTime(episodeId, fTime, tTime, getType);
                    break;
                case "AfOper":
                    for (CdcSurgeryEntity oper : surgeryEntities) {
                        if (oper.getStartDate() != null || oper.getEndDate() != null) {
                            endDate = oper.getEndDate();
                            break;
                        }
                    }
                    // 术后
                    fTime = DateUtil.getTime(startDate);
                    tTime = DateUtil.getTime(endDate);
                    operList = cdcSurgeryMapper.selectByTime(episodeId, fTime, tTime, getType);
                    break;
            }
        }
        return operList;
    }

    private String calcGetTimingForEmr(Long episodeId, Long valueTime) {
        String sqlStr = "";
        String filterSqlByDate = "AND (emr_date BETWEEN str_to_date('${sTime}','%Y-%m-%d %H:%i:%s') AND str_to_date('${eTime}', '%Y-%m-%d %H:%i:%s')) ORDER BY emr_date";
        String filterSqlByBefore = "AND emr_date < str_to_date('${sTime}','%Y-%m-%d %H:%i:%s') ORDER BY emr_date";
        String filterSqlByAfter = "AND (emr_date > str_to_date('${eTime}', '%Y-%m-%d %H:%i:%s')) ORDER BY emr_date";
        String filterSqlBySort = " ORDER BY IF(ISNULL(emr_date),1,0) ${seqType} ";
        String seqType = "";
        Long priorityId = 0L;
        Long tmpTime = 0L;
        String fTime = "";
        String tTime = "";

        // 如果没有配置采集时机，默认入院首次
        if (CommonUtil.isEmpty(valueTime)) {
            return "ORDER BY IF(ISNULL(emr_date),1,0) asc";
        }
        // 获取采集时间描述
        DictionaryEntity getTimingDic = dictionaryMapper.selectById(valueTime);
        String getType = getTimingDic.getCode();
        // 如果采集时机包含手术，则先取手术开始、结束时间
        if (getType.contains("Oper")) {
            Wrapper<CdcSurgeryEntity> operWpr = new EntityWrapper<>();
            operWpr.eq("episode_id", episodeId).eq("is_active", 1).orderBy("start_date");
            List<CdcSurgeryEntity> operList = cdcSurgeryMapper.selectList(operWpr);
            if (operList.size() == 0) {
                return "";
            }
            // 只取首次手术
            Date startDate = DateUtil.parse("1900-01-01 00:00:00");
            Date endDate = DateUtil.parse("1900-01-01 00:00:00");
            switch (getType) {
                case "BfOper":
                    for (CdcSurgeryEntity oper : operList) {
                        if (oper.getStartDate() != null || oper.getEndDate() != null) {
                            startDate = oper.getStartDate();
                            break;
                        }
                    }
                    // 术前
                    tmpTime = startDate.getTime();
                    fTime = DateUtil.getTime(new Date(tmpTime));
                    tTime = DateUtil.getTime(new Date(tmpTime));
                    sqlStr = filterSqlByBefore;
                    break;
                case "InOper":
                    for (CdcSurgeryEntity oper : operList) {
                        if (oper.getStartDate() != null && oper.getEndDate() != null) {
                            startDate = oper.getStartDate();
                            endDate = oper.getEndDate();
                            break;
                        }
                    }
                    // 术中
                    fTime = DateUtil.getTime(startDate);
                    tTime = DateUtil.getTime(endDate);
                    sqlStr = filterSqlByDate;
                    break;
                case "AfOper":
                    for (CdcSurgeryEntity oper : operList) {
                        if (oper.getStartDate() != null || oper.getEndDate() != null) {
                            endDate = oper.getEndDate();
                            break;
                        }
                    }
                    // 术后，默认手术后72小时
                    tmpTime = endDate.getTime();
                    fTime = DateUtil.getTime(endDate);
                    tTime = DateUtil.getTime(endDate);
                    sqlStr = filterSqlByAfter;
                    break;
                case "AllOper":
                    for (CdcSurgeryEntity oper : operList) {
                        if (oper.getStartDate() != null || oper.getEndDate() != null) {
                            startDate = oper.getStartDate();
                            endDate = oper.getEndDate();
                            break;
                        }
                    }
                    //围术期
                    tmpTime = startDate.getTime();
                    fTime = DateUtil.getTime(new Date(tmpTime - 3600 * 1000));
                    tmpTime = endDate.getTime();
                    tTime = DateUtil.getTime(new Date(tmpTime + 3 * 24 * 3600 * 1000));
                    sqlStr = filterSqlByDate;
                    break;
            }
        } else {
            // 获取就诊时间
            CdcEpisodeEntity admObj = cdcEpisodeMapper.selectById(episodeId);
            Date admDate = admObj.getAdmDate();
            Date dishDate = admObj.getDishDate();
            switch (getType) {
                case "Emergency":
                    // 急诊, 默认早于入院时间
                    tmpTime = admDate.getTime();
                    fTime = DateUtil.getTime(new Date(tmpTime - 24 * 3600 * 1000));
                    tTime = DateUtil.getTime(new Date(tmpTime));
                    sqlStr = filterSqlByDate;
                    break;
                case "LastInHosp":
                    // 住院末次
                    seqType = "DESC";
                    sqlStr = filterSqlBySort;
                    break;
                case "EMR-Inhos24":
                    // 急诊/入院24小时
                    tmpTime = admDate.getTime();
                    fTime = DateUtil.getTime(admDate);
                    tTime = DateUtil.getTime(new Date(tmpTime + 24 * 3600 * 1000));
                    sqlStr = filterSqlByDate;
                    break;
                case "DishHosMedi":
                    break;
                case "DurHosp":
                    // 住院期间 医嘱日期范围为住院期间
                    fTime = DateUtil.getTime(admDate);
                    tTime = DateUtil.getTime(dishDate);
                    sqlStr = filterSqlByDate;
                    break;
                default:
                    // 默认入院首次
                    seqType = "ASC";
                    sqlStr = filterSqlBySort;
                    break;
            }
        }
        Map<String, Object> map = new HashMap<>();
        map.put("sTime", fTime);
        map.put("eTime", tTime);
        map.put("seqType", seqType);
        map.put("priorityId", priorityId);
        StrSubstitutor strSubstitutor = new StrSubstitutor(map);
        sqlStr = strSubstitutor.replace(sqlStr);
        return sqlStr;
    }

    //type:1-手术；2-诊断;3-科室
    private Map<String, String> handleDicMatchParam(Long dicEntityId, Integer type) {
        Map<String, String> res = new HashMap<>();

        //排除关键字sql
        String kfilterTxt = "";
        //排除通用名sql
        String cfilterTxt = "";
        //同时满足关键字sql
        String kwordAndTxt = "";
        //同时满足通用名sql
        String cwordAndTxt = "";
        //满足一个关键字sql
        String kwordOrTxt = "";
        //满足一个通用名sql
        String cwordOrTxt = "";

        List<SdsStandDicMatchParamEntity> dicMatchParamEntities = sdsStandDicMatchParamMapper.selectList(new EntityWrapper<SdsStandDicMatchParamEntity>()
                .eq("dic_id", dicEntityId));
        for (SdsStandDicMatchParamEntity sdsStandDicMatchParam : dicMatchParamEntities) {
            if ("O".equals(sdsStandDicMatchParam.getFilterType())) {
                //O-排除 排除只处理对照内容只有一个的情况（包含&未考虑
                if ("K".equals(sdsStandDicMatchParam.getCompareType())) {
                    kfilterTxt = kfilterTxt + "|" + sdsStandDicMatchParam.getCompareContent();
                } else if ("C".equals(sdsStandDicMatchParam.getCompareType())) {
                    cfilterTxt = cfilterTxt + "|" + sdsStandDicMatchParam.getCompareContent();
                }
            } else if ("I".equals(sdsStandDicMatchParam.getFilterType())) {
                if ("K".equals(sdsStandDicMatchParam.getCompareType())) {
                    if (sdsStandDicMatchParam.getCompareContent().contains("&")) {
                        String[] split1 = sdsStandDicMatchParam.getCompareContent().split("&");
                        for (int i = 0; i <= split1.length - 1; i++) {
                            if (i == 0) {
                                kwordAndTxt = kwordAndTxt + " or description like '%" + split1[0] + "%'";
                            } else {
                                kwordAndTxt = kwordAndTxt + " and description like '%" + split1[i] + "%'";
                            }
                        }
                    } else {
                        kwordOrTxt = kwordOrTxt + "|" + sdsStandDicMatchParam.getCompareContent();
                    }
                } else if ("C".equals(sdsStandDicMatchParam.getCompareType())) {
                    if (sdsStandDicMatchParam.getCompareContent().contains("&")) {
                        String[] split2 = sdsStandDicMatchParam.getCompareContent().split("&");
                        for (int i = 0; i <= split2.length - 1; i++) {
                            if (i == 0) {
                                cwordAndTxt = cwordAndTxt + " or drug_common_name like '%" + split2[0] + "%'";
                            } else {
                                cwordAndTxt = cwordAndTxt + " and drug_common_name like '%" + split2[i] + "%'";
                            }
                        }
                    } else {
                        cwordOrTxt = cwordOrTxt + "|" + sdsStandDicMatchParam.getCompareContent();
                    }
                }
            }
        }

        if ("" != kwordOrTxt) {
            kwordOrTxt = kwordOrTxt.substring(1, kwordOrTxt.length());
        }
        if ("" != kwordAndTxt) {
            if (1 == type) {
                kwordAndTxt = kwordAndTxt.replace("description", "code");
            }
            if (2 == type) {
                kwordAndTxt = kwordAndTxt.replace("description", "icd10");
            }
            if (3 == type) {
                kwordAndTxt = kwordAndTxt.replace("description", "adm_loc_desc");
            }
        }
        if ("" != cwordOrTxt) {
            cwordOrTxt = cwordOrTxt.substring(1, cwordOrTxt.length());
        }
        if ("" != kfilterTxt) {
            kfilterTxt = kfilterTxt.substring(1, kfilterTxt.length());
        }
        if ("" != cfilterTxt) {
            cfilterTxt = cfilterTxt.substring(1, cfilterTxt.length());
        }
        if ("" != kwordAndTxt && ("" == kwordOrTxt || "" == cwordOrTxt)) {
            kwordAndTxt = kwordAndTxt.replaceFirst("or", "and");
        }
        if ("" != cwordAndTxt && ("" == kwordOrTxt || "" == cwordOrTxt)) {
            cwordAndTxt = cwordAndTxt.replaceFirst("or", "and");
        }

        res.put("kfilterTxt", kfilterTxt);
        res.put("cfilterTxt", cfilterTxt);
        res.put("kwordAndTxt", kwordAndTxt);
        res.put("cwordAndTxt", cwordAndTxt);
        res.put("kwordOrTxt", kwordOrTxt);
        res.put("cwordOrTxt", cwordOrTxt);

        return res;
    }

    private Map<String, String> handleLocMatchParam(Long dicEntityId) {
        Map<String, String> res = new HashMap<>();
        //排除的字符串
        String filterTxt = "";
        //满足的字符串
        String wordOrTxt = "";
        List<SdsStandDicMatchParamEntity> dicMatchParamEntities = sdsStandDicMatchParamMapper.selectList(new EntityWrapper<SdsStandDicMatchParamEntity>()
                .eq("dic_id", dicEntityId));
        for (SdsStandDicMatchParamEntity sdsStandDicMatchParam : dicMatchParamEntities) {
            if ("O".equals(sdsStandDicMatchParam.getFilterType())) {
                filterTxt = filterTxt + "|" + sdsStandDicMatchParam.getCompareContent();
            } else if ("I".equals(sdsStandDicMatchParam.getFilterType())) {
                wordOrTxt = wordOrTxt + "|" + sdsStandDicMatchParam.getCompareContent();
            }
        }

        res.put("filterTxt", filterTxt);
        res.put("wordOrTxt", wordOrTxt);
        return res;
    }

    /**
     * 根据就诊号获取【慢阻肺】相关VTE结果
     *
     * @param episodeId
     * @return
     */
    private String getMZFitem(String episodeId, Long itemId, String sourceCode, String subUrl) {
        String result = "";
        JSONObject obj = this.vteHttpGet(subUrl, episodeId);
        int status = obj.getInteger("code");
        if (status == 200) {
            Object strObj = obj.getJSONObject("data").get(sourceCode);
            if (CommonUtil.equals(sourceCode, "isHighRisk")) {
                if ((int) strObj == 1) {
                    result = "y";
                } else {
                    result = "n";
                }
            } else if (CommonUtil.equals(sourceCode, "treatList")) {
                if (CommonUtil.isNotEmpty(strObj)) {
                    JSONArray array = JSONArray.parseArray(String.valueOf(strObj));
                    // 获取值域字典
//                    Wrapper<SdsQcfitemDicEntity> itemDicWpr = new EntityWrapper<>();
//                    itemDicWpr.eq("form_item_id", itemId).eq("is_active", 1);
//                    List<SdsQcfitemDicEntity> itemDicList = sdsQcfitemDicMapper.selectList(itemDicWpr);
                    List<SdsQcfitemDicEntity> itemDicList = FormItemDicCache.me().getFormItemDicList(itemId);
                    a:
                    for (SdsQcfitemDicEntity dic : itemDicList) {
                        for (int i = 0; i < array.size(); i++) {
                            /*if (CommonUtil.isNotEmpty(dic.getKeyword())) {
                                if (dic.getKeyword().equals(array.getString(i))) {
                                    result += dic.getCode() + ",";
                                    continue a;
                                }
                            } else {
                                if (dic.getDesc().contains(array.getString(i))) {
                                    result += dic.getCode() + ",";
                                    continue a;
                                }
                            }*/
                            if (dic.getDesc().contains(array.getString(i))) {
                                result += dic.getCode() + ",";
                                continue a;
                            }
                        }
                    }
                }
            } else if (CommonUtil.equals(sourceCode, "otherTreat")) {
                if (CommonUtil.isNotEmpty(strObj)) {
                    result = String.valueOf(strObj);
                }
            }
        }
        return result;
    }

    /**
     * 根据就诊号获取【围术期预深静脉血栓】相关VTE结果 或 【中高危风险患者预防静脉血栓】相关VTE结果
     *
     * @param episodeId
     * @return
     */
    private String getWSQAndZGWitem(String episodeId, Long itemId, String sourceCode, String subUrl) {
        String result = "";
        JSONObject obj = this.vteHttpGet(subUrl, episodeId);
        int status = obj.getInteger("code");
        if (status == 200) {
            Object strObj = obj.getJSONObject("data").get(sourceCode);
            if (CommonUtil.isNotEmpty(strObj)) {
                if (CommonUtil.equals(sourceCode, "score")) {
                    result = String.valueOf(strObj);
                } else {
                    // 获取值域字典
//                    Wrapper<SdsQcfitemDicEntity> itemDicWpr = new EntityWrapper<>();
//                    itemDicWpr.eq("form_item_id", itemId).eq("is_active", 1);
//                    List<SdsQcfitemDicEntity> itemDicList = sdsQcfitemDicMapper.selectList(itemDicWpr);
                    List<SdsQcfitemDicEntity> itemDicList = FormItemDicCache.me().getFormItemDicList(itemId);
                    for (SdsQcfitemDicEntity dic : itemDicList) {
                       /* if (CommonUtil.isNotEmpty(dic.getKeyword())) {
                            if (dic.getKeyword().equals(strObj.toString())) {
                                result = dic.getCode();
                                break;
                            }
                        } else {
                            if (dic.getDesc().contains(strObj.toString())) {
                                result = dic.getCode();
                                break;
                            }
                        }*/
                        if (dic.getDesc().contains(strObj.toString())) {
                            result = dic.getCode();
                            break;
                        }
                    }
                }
            }
        }
        return result;
    }

    private JSONObject vteHttpGet(String subUrl, String episodeId) {
        JSONObject obj = new JSONObject();
        // VTE服务url
        String vteServerUrl = CdcConfigCache.me().getValueByKey("SDS", "VTEServer");
        // 创建httpClient对象
        CloseableHttpClient client = HttpClients.createDefault();
        // 创建请求方法的实例，并指定请求URL
        String url = vteServerUrl + subUrl + episodeId;
        HttpGet get = new HttpGet(url);
        // 调用execute,返回response
        CloseableHttpResponse response = null;
        try {
            response = client.execute(get);
            String str = EntityUtils.toString(response.getEntity());
            obj = JSONObject.parseObject(str);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (client != null) {
                    client.close();
                }
                if (response != null) {
                    response.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return obj;
    }

    /**
     * 通过配置逻辑表达式计算项目结果
     *
     * @param mrListId
     * @param mrListId
     * @param dataConfig
     * @param entityId
     * @param dataConfig
     * @param type
     * @return
     */
    public String LogicValue(Long episodeId, Long mrListId, Long entityId, SdsDataConfigEntity dataConfig, Integer type) {
        String resultStr = "";

        if (dataConfig == null || CommonUtil.isEmpty(dataConfig.getCalcExp())) return resultStr;
        // 运行表达式结果且返回
        ScriptEngineManager manager = new ScriptEngineManager();
        ScriptEngine engine = manager.getEngineByName("JavaScript");

        String exexExp = dataConfig.getCalcExp();
        String originExp = exexExp;
        try {
            // 查找规则公式中括号以内的字符
            Pattern p = Pattern.compile("\\(.*?\\)");// 查找规则公式中括号以内的字符
            Matcher m = p.matcher(exexExp);
            while (m.find()) {// 遍历找到的所有括号
                if (m.group().contains("\"")) { // 如果里面是常量，则继续下一个
                    continue;
                }
                // 取得关联项目代码
                String itemCode = m.group().substring(1, m.group().length() - 1);
                // 通过项目代码查询项目id并取值
                String linkVal = getLinkItemValue(mrListId, entityId, itemCode);
                if (StringUtils.isEmpty(linkVal)){
                    return resultStr;
                }
                // 如果表达式有引号，那么是字符串比较，给项目值加上双引号
                linkVal = "(\"" + linkVal + "\")";
                // 将值替换表达式中项目代码
                exexExp = exexExp.replace(m.group(), linkVal);
            }
            if (!exexExp.matches("\\{.*?\\}")) {
                String[] expArr = exexExp.split(":", 2);
                String subExpType_l = "";
                String subExp_l = "";
                if (expArr.length < 2) {
                    subExp_l = expArr[0];
                } else {
                    subExpType_l = expArr[0];
                    subExp_l = expArr[1];
                }
                resultStr = this.parseExpStr(subExpType_l, subExp_l);
            } else {
                // 查找规则公式中大括号以内的字符
                Pattern pat3 = Pattern.compile("\\{.*?\\}");
                // 替换关联项目的值
                Matcher m3 = pat3.matcher(exexExp);
                while (m3.find()) {
                    // 大括号中间的表达式
                    String subExpStr_l = m3.group().substring(1, m3.group().length() - 1);
                    String[] expArr = subExpStr_l.split(":", 2);
                    String subExpType_l = "";
                    String subExp_l = "";
                    if (expArr.length < 2) {
                        subExp_l = expArr[0];
                    } else {
                        subExpType_l = expArr[0];
                        subExp_l = expArr[1];
                    }
                    // 根据计算规则处理值
                    String subResult = this.parseExpStr(subExpType_l, subExp_l);
                    exexExp = exexExp.replace(subExpStr_l, subResult);
                }
                // 将表达式中的大括号中括号替换为小括号，以及其他其他字符替换为可执行字符
                exexExp = exexExp.replace("{", "(").replace("}", ")");
                exexExp = exexExp.replace("[", "(").replace("]", ")");

                resultStr = String.valueOf(engine.eval(exexExp));
            }
            if (resultStr.contains(".")) { // 计算结果精度问题，取小数点后两位
                resultStr = resultStr.substring(0, resultStr.indexOf(".") + 3);
            }
            if (type == 2) {
                if (CommonUtil.equals(resultStr, "true")) {
                    resultStr = "true"; //仅以此代表结果满足
                } else {
                    resultStr = "";
                }
            }
        } catch (Exception e) {
            log.error("自动取值在计算表达式时出错：【" + originExp + "】");
        }

        return resultStr;
    }

    private String parseExpStr(String subExpType_l, String subExp_l) {
        // 运行表达式结果且返回
        ScriptEngineManager manager = new ScriptEngineManager();
        ScriptEngine engine = manager.getEngineByName("JavaScript");
        String orgionStr = subExp_l;
        if (CommonUtil.equals(subExpType_l, "CONST")) {
            return subExp_l;
        }
        long divisor = 1;
        if (subExpType_l.contains("CALC")) {
            String dateType = subExpType_l.split("#")[0];
            switch (dateType) {
                case "CALC-h":
                    // 1小时毫秒数
                    divisor = 60 * 60 * 1000;
                    break;
                case "CALC-h-radio":
                    // 1小时毫秒数
                    divisor = 60 * 60 * 1000;
                    break;
                case "CALC-m":
                    // 一分钟毫秒数
                    divisor = 60 * 1000;
                    break;
                case "CALC-day":
                    // 一天毫秒数
                    divisor = 24 * 60 * 60 * 1000;
                    break;
                case "CALC-month":
                    // 一个月毫秒数
                    divisor = 30l * 24l * 60l * 60l * 1000l;
                    break;
                case "CALC-year":
                    // 一年毫秒数
                    divisor = 12l * 30l * 24l * 60l * 60l * 1000l;
                    break;
                default:
                    break;
            }
            // 查找规则公式中小括号以内的值
            // 替换关联项目的值
            // 查找规则公式中括号以内的字符
            Pattern p = Pattern.compile("\\(.*?\\)");// 查找规则公式中括号以内的字符
            Matcher m = p.matcher(subExp_l);
            String tmpExecExp = subExp_l;
            while (m.find()) {
                if ("()".equals(m.group()) || "(\"\")".equals(m.group())) {
                    tmpExecExp = tmpExecExp.replace(m.group(), "0");
                    continue;
                }
                String val = m.group().substring(1, m.group().length() - 1).replace("\"", "");
                Long times = com.dhcc.sds.util.DateUtil.getTime(val);
                int minutes = Math.toIntExact(times / divisor);
                tmpExecExp = tmpExecExp.replace(val, String.valueOf(minutes));
            }
            subExp_l = subExp_l.replace(subExp_l, tmpExecExp);
            subExp_l = subExp_l.replace("\"", "");
        }
        String subResult = "";
        try {
            subExp_l = subExp_l.replace(":", "");
            // 将表达式中的大括号中括号替换为小括号，以及其他其他字符替换为可执行字符
            subExp_l = subExp_l.replace("{", "(").replace("}", ")");
            subExp_l = subExp_l.replace("[", "(").replace("]", ")");
            subExp_l = subExp_l.replace("contains(\"\")", "contains(\",,\")");
            subExp_l = subExp_l.replace("oth", "OTH").replace("def", "DEF");

            subResult = String.valueOf(engine.eval(subExp_l));
            // 含有CLAC，但计算结果不是true、false,说明是时间加减计算后的时间
            if (subExpType_l.contains("CALC") && (CommonUtil.notEquals(subResult, "true") && CommonUtil.notEquals(subResult, "false"))) {
                if (subExpType_l.split("#").length>1) { //20240115 如果含有#r，如CALC-h#r,直接返回计算值
                    Date date = new Date(Long.valueOf(subResult) * divisor);
                    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                    subResult = sdf.format(date);
                }
            }
            if ("CALC-h-radio".equals(subExpType_l)) {
                if ("true".equals(subResult)) {
                    subResult = "y";
                } else if ("false".equals(subResult)) {
                    subResult = "n";
                }
            }
        } catch (ScriptException e) {
            log.error("自动取值在计算表达式时出错：【" + orgionStr + "】");
        }
        return subResult;
    }

    /**
     * 实现获取关联项目值的逻辑
     *
     * @param mrListId
     * @param entityId
     * @param itemCode
     * @return
     */
    private String getLinkItemValue(Long mrListId, Long entityId, String itemCode) {
        // 取得关联项目代码
        // 通过项目代码查询项目id并取值
        String linkVal = "";
        SdsQcformItemEntity linkItem = FormItemCache.me().getFormItemByCode(entityId, itemCode);

        Wrapper<SdsQcfitemExecresultEntity> execWpr = new EntityWrapper<>();
        execWpr.eq("in_case_id", mrListId);
        execWpr.eq("form_item_id", linkItem.getId());
        SdsQcfitemExecresultEntity linkItemExec = sdsQcfitemExecresultService.selectOne(execWpr);
        // 如果有项目值为空，则默认不符合
        if (!CommonUtil.isEmpty(linkItemExec)) {
            linkVal = linkItemExec.getItemResult();
        }
        return linkVal;
    }

    public Map<String,String> CustomEntity(List<CdcEpisodeEntity> episodeEntities, Long datasourceId){
        Map<String,String> resMap = new HashMap<>();
        String value = "0";
        BigDecimal numerator = new BigDecimal("0");
        BigDecimal denominator = new BigDecimal("0");
        StringBuilder epIds = new StringBuilder("-1,");
        StringBuilder epIdsOpp = new StringBuilder("-1,");
        if (CommonUtil.isEmpty(episodeEntities)){
            return resMap;
        }
        SdsStandSourceEntity source = sdsStandSourceMapper.selectById(datasourceId);
        if (!StringUtils.isEmpty(source)) {
            String sourceCode = source.getSourceCode();
            switch (sourceCode){
                case "EntityCount":
                    value = String.valueOf(episodeEntities.size());
                    numerator = new BigDecimal(value);
                    break;
                case "DiedRate":
                    int died = 0;
                    for (CdcEpisodeEntity episodeEntity : episodeEntities) {
                        if (episodeEntity.getIsDeath().equals(1)){
                            died += 1;
                            epIds.append(episodeEntity.getId()).append(",");
                        }else {
                            epIdsOpp.append(episodeEntity.getId()).append(",");
                        }
                    }
                    numerator = new BigDecimal(died);
                    denominator = new BigDecimal(episodeEntities.size());
                    BigDecimal r = numerator.divide(denominator,2, RoundingMode.HALF_UP);
                    NumberFormat percent = NumberFormat.getPercentInstance();
                    percent.setMaximumFractionDigits(2);
                    value = percent.format(r.doubleValue());
                    break;
                case "FeeMedian":
                    List<BigDecimal> list = new ArrayList<>();
                    for (CdcEpisodeEntity episodeEntity : episodeEntities) {
                        List<List<Map<String, Object>>> feeResList = (List<List<Map<String, Object>>>)EprFeeInfo(episodeEntity.getId(), 69l, null, null, null);
                        for (List<Map<String, Object>> maps : feeResList) {
                            for (Map<String, Object> map : maps) {
                                BigDecimal fee = new BigDecimal(map.get("fee1").toString());
                                list.add(fee);
                            }
                        }
                    }
                    value = findMedian(list).toString();
                    numerator = new BigDecimal(value);
                    break;
                case "FeeAverage":
                    list = new ArrayList<>();
                    for (CdcEpisodeEntity episodeEntity : episodeEntities) {
                        List<List<Map<String, Object>>> feeResList = (List<List<Map<String, Object>>>)EprFeeInfo(episodeEntity.getId(), 69l, null, null, null);
                        for (List<Map<String, Object>> maps : feeResList) {
                            for (Map<String, Object> map : maps) {
                                BigDecimal fee = new BigDecimal(map.get("fee1").toString());
                                list.add(fee);
                            }
                        }
                    }
                    value = average(list,2,4).toString();
                    numerator = new BigDecimal(value);
                    break;
                case "HospitalDay":
                    list = new ArrayList<>();
                    for (CdcEpisodeEntity episodeEntity : episodeEntities) {
                        Integer admDays = episodeEntity.getAdmDays();
                        if (admDays==-1||ObjectUtils.isEmpty(admDays)) continue;
                        list.add(new BigDecimal(admDays));
                    }
                    value = average(list,0,4).toString();
                    numerator = new BigDecimal(value);
                    break;
            }
        }
        resMap.put("epIds",epIds.toString());
        resMap.put("epIdsOpp",epIdsOpp.toString());
        resMap.put("value",value);
        resMap.put("numerator",numerator.toString());
        resMap.put("denominator",denominator.toString());
        return resMap;
    }
    private BigDecimal average(List<BigDecimal> decimalList, Integer scale, int roundingMode) {
        if(CollectionUtils.isEmpty(decimalList)) return BigDecimal.ZERO;
        BigDecimal sum = decimalList.stream()
                .map(x-> Optional.ofNullable(x).orElse(BigDecimal.ZERO))
                .reduce(BigDecimal.ZERO, BigDecimal::add);
        long count = decimalList.size();
        return sum.divide(new BigDecimal(count), scale, roundingMode);
    }

    public BigDecimal findMedian(List<BigDecimal> decimalList) {
        if(CollectionUtils.isEmpty(decimalList)) return BigDecimal.ZERO;
        Collections.sort(decimalList);
        int size = decimalList.size();
        int middleIndex = size / 2;
        if (size % 2 == 0) {
            return decimalList.get(middleIndex - 1).add(decimalList.get(middleIndex))
                    .divide(new BigDecimal(2),2,4);
        } else {
            return decimalList.get(middleIndex);
        }
    }
}
